<head>
	<meta charset="UTF-8">
  <meta itemprop="name" content="A Tour of the Dart Language | DartLang.org">
</head>
<body>
<div lang="zh" dir="ltr" class="mw-content-ltr"><p><br>
<i>本文译自 Dart 语言官网 <a rel="nofollow" class="external text" href="http://www.dartlang.org/language-tour/">A Tour of the Dart Language</a> 一文，原作者为 Kathy &amp; Seth。原文授权许可为 <a rel="nofollow" class="external text" href="http://creativecommons.org/licenses/by/3.0/">CC-BY 3.0</a>。</i>
</p><p>欢迎参观 Dart 语言!
在这里您将看到 Dart 各项主要功能的用法，
包括变量、运算符、类、库等。
本文假定您已经了解如何用其他语言编程。
</p>
<div class="note">
<p><b>提示：</b>
如需尝试各项功能，请使用
<a href="/wiki/Docs/Getting_Started/Editor" title="Docs/Getting Started/Editor">Dart Editor</a>
创建服务器应用项目。
</p>
</div>
<p>如需详细了解某项语言功能，请参考
<a href="/action/edit/Docs/Specification?redlink=1" class="new" title="Docs/Specification（尚未撰写）">Dart 语言规范</a>
。
</p>
<table align="right">
<tbody><tr>
<td> <table id="toc" class="toc"><tbody><tr><td><div id="toctitle"><h2>目录</h2></div>
<ul>
<li class="toclevel-1 tocsection-1"><a href="#.E5.9F.BA.E6.9C.AC.E7.9A.84_Dart_.E7.A8.8B.E5.BA.8F"><span class="tocnumber">1</span> <span class="toctext">基本的 Dart 程序</span></a>
<ul>
<li class="toclevel-2 tocsection-2"><a href="#main.28.29"><span class="tocnumber">1.1</span> <span class="toctext">main()</span></a></li>
<li class="toclevel-2 tocsection-3"><a href="#.2F.2F"><span class="tocnumber">1.2</span> <span class="toctext">//</span></a></li>
<li class="toclevel-2 tocsection-4"><a href="#int.2C_String"><span class="tocnumber">1.3</span> <span class="toctext">int, String</span></a></li>
<li class="toclevel-2 tocsection-5"><a href="#.22....22_.28.E6.88.96_.27....27.29"><span class="tocnumber">1.4</span> <span class="toctext">"..." (或 '...')</span></a></li>
<li class="toclevel-2 tocsection-6"><a href="#.24.E5.8F.98.E9.87.8F.E5.90.8D"><span class="tocnumber">1.5</span> <span class="toctext">$变量名</span></a></li>
<li class="toclevel-2 tocsection-7"><a href="#print.28.29"><span class="tocnumber">1.6</span> <span class="toctext">print()</span></a></li>
<li class="toclevel-2 tocsection-8"><a href="#.E6.A0.B7.E5.BC.8F"><span class="tocnumber">1.7</span> <span class="toctext">样式</span></a></li>
<li class="toclevel-2 tocsection-9"><a href="#.E8.BF.90.E8.A1.8C.E6.97.B6.E6.A8.A1.E5.BC.8F"><span class="tocnumber">1.8</span> <span class="toctext">运行时模式</span></a></li>
</ul>
</li>
<li class="toclevel-1 tocsection-10"><a href="#.E5.8F.98.E9.87.8F"><span class="tocnumber">2</span> <span class="toctext">变量</span></a>
<ul>
<li class="toclevel-2 tocsection-11"><a href="#.E9.BB.98.E8.AE.A4.E5.80.BC"><span class="tocnumber">2.1</span> <span class="toctext">默认值</span></a></li>
<li class="toclevel-2 tocsection-12"><a href="#.E5.8F.AF.E9.80.89.E7.B1.BB.E5.9E.8B"><span class="tocnumber">2.2</span> <span class="toctext">可选类型</span></a></li>
<li class="toclevel-2 tocsection-13"><a href="#final"><span class="tocnumber">2.3</span> <span class="toctext">final</span></a></li>
<li class="toclevel-2 tocsection-14"><a href="#.E5.B0.8F.E7.BB.93"><span class="tocnumber">2.4</span> <span class="toctext">小结</span></a></li>
</ul>
</li>
<li class="toclevel-1 tocsection-15"><a href="#.E5.86.85.E7.BD.AE.E7.B1.BB.E5.9E.8B"><span class="tocnumber">3</span> <span class="toctext">内置类型</span></a>
<ul>
<li class="toclevel-2 tocsection-16"><a href="#.E5.AD.97.E7.AC.A6.E4.B8.B2"><span class="tocnumber">3.1</span> <span class="toctext">字符串</span></a>
<ul>
<li class="toclevel-3 tocsection-17"><a href="#.E5.AD.97.E7.AC.A6.E4.B8.B2.E6.96.B9.E6.B3.95"><span class="tocnumber">3.1.1</span> <span class="toctext">字符串方法</span></a></li>
<li class="toclevel-3 tocsection-18"><a href="#StringBuffer_.E6.96.B9.E6.B3.95"><span class="tocnumber">3.1.2</span> <span class="toctext">StringBuffer 方法</span></a></li>
</ul>
</li>
<li class="toclevel-2 tocsection-19"><a href="#.E6.95.B0.E5.AD.97"><span class="tocnumber">3.2</span> <span class="toctext">数字</span></a>
<ul>
<li class="toclevel-3 tocsection-20"><a href="#int"><span class="tocnumber">3.2.1</span> <span class="toctext">int</span></a></li>
<li class="toclevel-3 tocsection-21"><a href="#double"><span class="tocnumber">3.2.2</span> <span class="toctext">double</span></a></li>
</ul>
</li>
<li class="toclevel-2 tocsection-22"><a href="#.E5.B8.83.E5.B0.94"><span class="tocnumber">3.3</span> <span class="toctext">布尔</span></a></li>
<li class="toclevel-2 tocsection-23"><a href="#.E5.88.97.E8.A1.A8.EF.BC.88.E5.8D.B3.E6.95.B0.E7.BB.84.EF.BC.89"><span class="tocnumber">3.4</span> <span class="toctext">列表（即数组）</span></a>
<ul>
<li class="toclevel-3 tocsection-24"><a href="#.E9.81.8D.E5.8E.86"><span class="tocnumber">3.4.1</span> <span class="toctext">遍历</span></a></li>
<li class="toclevel-3 tocsection-25"><a href="#.E5.88.97.E8.A1.A8.E4.B8.8E.E9.9B.86.E5.90.88.E6.96.B9.E6.B3.95"><span class="tocnumber">3.4.2</span> <span class="toctext">列表与集合方法</span></a></li>
</ul>
</li>
<li class="toclevel-2 tocsection-26"><a href="#.E6.98.A0.E5.B0.84"><span class="tocnumber">3.5</span> <span class="toctext">映射</span></a>
<ul>
<li class="toclevel-3 tocsection-27"><a href="#.E9.81.8D.E5.8E.86_2"><span class="tocnumber">3.5.1</span> <span class="toctext">遍历</span></a></li>
</ul>
</li>
<li class="toclevel-2 tocsection-28"><a href="#.E5.86.85.E7.BD.AE.E7.B1.BB.E5.9E.8B.E5.B0.8F.E7.BB.93"><span class="tocnumber">3.6</span> <span class="toctext">内置类型小结</span></a></li>
</ul>
</li>
<li class="toclevel-1 tocsection-29"><a href="#.E5.87.BD.E6.95.B0"><span class="tocnumber">4</span> <span class="toctext">函数</span></a>
<ul>
<li class="toclevel-2 tocsection-30"><a href="#.E5.8F.AF.E9.80.89.E5.8F.82.E6.95.B0"><span class="tocnumber">4.1</span> <span class="toctext">可选参数</span></a></li>
<li class="toclevel-2 tocsection-31"><a href="#.E5.8F.AF.E9.80.89.E5.8F.82.E6.95.B0.E7.9A.84.E9.BB.98.E8.AE.A4.E5.80.BC"><span class="tocnumber">4.2</span> <span class="toctext">可选参数的默认值</span></a></li>
<li class="toclevel-2 tocsection-32"><a href="#.E5.91.BD.E5.90.8D.E5.8F.82.E6.95.B0"><span class="tocnumber">4.3</span> <span class="toctext">命名参数</span></a></li>
<li class="toclevel-2 tocsection-33"><a href="#.E7.AC.AC.E4.B8.80.E7.B1.BB.E5.87.BD.E6.95.B0"><span class="tocnumber">4.4</span> <span class="toctext">第一类函数</span></a></li>
<li class="toclevel-2 tocsection-34"><a href="#.E8.AF.8D.E6.B3.95.E5.B0.81.E8.A3.85"><span class="tocnumber">4.5</span> <span class="toctext">词法封装</span></a></li>
<li class="toclevel-2 tocsection-35"><a href="#.E8.BF.94.E5.9B.9E.E5.80.BC"><span class="tocnumber">4.6</span> <span class="toctext">返回值</span></a></li>
<li class="toclevel-2 tocsection-36"><a href="#.E5.87.BD.E6.95.B0.E5.B0.8F.E7.BB.93"><span class="tocnumber">4.7</span> <span class="toctext">函数小结</span></a></li>
</ul>
</li>
<li class="toclevel-1 tocsection-37"><a href="#.E8.BF.90.E7.AE.97.E7.AC.A6"><span class="tocnumber">5</span> <span class="toctext">运算符</span></a>
<ul>
<li class="toclevel-2 tocsection-38"><a href="#.E7.AE.97.E6.9C.AF.E8.BF.90.E7.AE.97.E7.AC.A6"><span class="tocnumber">5.1</span> <span class="toctext">算术运算符</span></a></li>
<li class="toclevel-2 tocsection-39"><a href="#.E7.9B.B8.E7.AD.89.E6.80.A7.E4.B8.8E.E5.85.B3.E7.B3.BB.E8.BF.90.E7.AE.97.E7.AC.A6"><span class="tocnumber">5.2</span> <span class="toctext">相等性与关系运算符</span></a></li>
<li class="toclevel-2 tocsection-40"><a href="#.E8.B5.8B.E5.80.BC.E8.BF.90.E7.AE.97.E7.AC.A6"><span class="tocnumber">5.3</span> <span class="toctext">赋值运算符</span></a></li>
<li class="toclevel-2 tocsection-41"><a href="#.E9.80.BB.E8.BE.91.E8.BF.90.E7.AE.97.E7.AC.A6"><span class="tocnumber">5.4</span> <span class="toctext">逻辑运算符</span></a></li>
<li class="toclevel-2 tocsection-42"><a href="#.E4.BD.8D.E6.93.8D.E4.BD.9C.E4.B8.8E.E7.A7.BB.E4.BD.8D.E8.BF.90.E7.AE.97.E7.AC.A6"><span class="tocnumber">5.5</span> <span class="toctext">位操作与移位运算符</span></a></li>
<li class="toclevel-2 tocsection-43"><a href="#.E5.85.B6.E4.BB.96.E8.BF.90.E7.AE.97.E7.AC.A6"><span class="tocnumber">5.6</span> <span class="toctext">其他运算符</span></a></li>
<li class="toclevel-2 tocsection-44"><a href="#.E8.BF.90.E7.AE.97.E7.AC.A6.E7.9A.84.E6.96.B9.E6.B3.95.E6.9C.AC.E8.B4.A8"><span class="tocnumber">5.7</span> <span class="toctext">运算符的方法本质</span></a></li>
<li class="toclevel-2 tocsection-45"><a href="#.E8.BF.90.E7.AE.97.E7.AC.A6.E5.B0.8F.E7.BB.93"><span class="tocnumber">5.8</span> <span class="toctext">运算符小结</span></a></li>
</ul>
</li>
<li class="toclevel-1 tocsection-46"><a href="#.E6.B5.81.E7.A8.8B.E6.8E.A7.E5.88.B6"><span class="tocnumber">6</span> <span class="toctext">流程控制</span></a>
<ul>
<li class="toclevel-2 tocsection-47"><a href="#if_.E4.B8.8E_else"><span class="tocnumber">6.1</span> <span class="toctext">if 与 else</span></a></li>
<li class="toclevel-2 tocsection-48"><a href="#for_.E5.BE.AA.E7.8E.AF"><span class="tocnumber">6.2</span> <span class="toctext">for 循环</span></a></li>
<li class="toclevel-2 tocsection-49"><a href="#while_.E4.B8.8E_do_while"><span class="tocnumber">6.3</span> <span class="toctext">while 与 do while</span></a></li>
<li class="toclevel-2 tocsection-50"><a href="#break_.E4.B8.8E_continue"><span class="tocnumber">6.4</span> <span class="toctext">break 与 continue</span></a></li>
<li class="toclevel-2 tocsection-51"><a href="#switch_.E4.B8.8E_case"><span class="tocnumber">6.5</span> <span class="toctext">switch 与 case</span></a></li>
</ul>
</li>
<li class="toclevel-1 tocsection-52"><a href="#.E5.BC.82.E5.B8.B8.E5.A4.84.E7.90.86"><span class="tocnumber">7</span> <span class="toctext">异常处理</span></a>
<ul>
<li class="toclevel-2 tocsection-53"><a href="#.E6.8A.9B.E5.87.BA"><span class="tocnumber">7.1</span> <span class="toctext">抛出</span></a></li>
<li class="toclevel-2 tocsection-54"><a href="#.E6.8D.95.E6.8D.89"><span class="tocnumber">7.2</span> <span class="toctext">捕捉</span></a></li>
<li class="toclevel-2 tocsection-55"><a href="#finally"><span class="tocnumber">7.3</span> <span class="toctext">finally</span></a></li>
</ul>
</li>
<li class="toclevel-1 tocsection-56"><a href="#.E7.B1.BB"><span class="tocnumber">8</span> <span class="toctext">类</span></a>
<ul>
<li class="toclevel-2 tocsection-57"><a href="#.E5.AE.9E.E4.BE.8B.E5.8F.98.E9.87.8F"><span class="tocnumber">8.1</span> <span class="toctext">实例变量</span></a>
<ul>
<li class="toclevel-3 tocsection-58"><a href="#.E5.AE.9E.E4.BE.8B.E5.8F.98.E9.87.8F.E7.9A.84.E5.88.9D.E5.A7.8B.E5.8C.96"><span class="tocnumber">8.1.1</span> <span class="toctext">实例变量的初始化</span></a></li>
</ul>
</li>
<li class="toclevel-2 tocsection-59"><a href="#.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0"><span class="tocnumber">8.2</span> <span class="toctext">构造函数</span></a>
<ul>
<li class="toclevel-3 tocsection-60"><a href="#.E9.BB.98.E8.AE.A4.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0"><span class="tocnumber">8.2.1</span> <span class="toctext">默认构造函数</span></a></li>
<li class="toclevel-3 tocsection-61"><a href="#.E5.88.9D.E5.A7.8B.E5.8C.96.E5.88.97.E8.A1.A8"><span class="tocnumber">8.2.2</span> <span class="toctext">初始化列表</span></a></li>
<li class="toclevel-3 tocsection-62"><a href="#.E5.91.BD.E5.90.8D.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0"><span class="tocnumber">8.2.3</span> <span class="toctext">命名构造函数</span></a></li>
<li class="toclevel-3 tocsection-63"><a href="#.E5.B8.B8.E9.87.8F.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0"><span class="tocnumber">8.2.4</span> <span class="toctext">常量构造函数</span></a></li>
<li class="toclevel-3 tocsection-64"><a href="#factory_.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0"><span class="tocnumber">8.2.5</span> <span class="toctext">factory 构造函数</span></a></li>
</ul>
</li>
<li class="toclevel-2 tocsection-65"><a href="#.E6.96.B9.E6.B3.95"><span class="tocnumber">8.3</span> <span class="toctext">方法</span></a>
<ul>
<li class="toclevel-3 tocsection-66"><a href="#.E5.AE.9E.E4.BE.8B.E6.96.B9.E6.B3.95"><span class="tocnumber">8.3.1</span> <span class="toctext">实例方法</span></a></li>
<li class="toclevel-3 tocsection-67"><a href="#getter_.E4.B8.8E_setter"><span class="tocnumber">8.3.2</span> <span class="toctext">getter 与 setter</span></a></li>
<li class="toclevel-3 tocsection-68"><a href="#.E8.BF.90.E7.AE.97.E7.AC.A6_2"><span class="tocnumber">8.3.3</span> <span class="toctext">运算符</span></a></li>
</ul>
</li>
<li class="toclevel-2 tocsection-69"><a href="#.E6.8A.BD.E8.B1.A1.E7.B1.BB"><span class="tocnumber">8.4</span> <span class="toctext">抽象类</span></a></li>
<li class="toclevel-2 tocsection-70"><a href="#.E6.89.A9.E5.B1.95.E7.B1.BB"><span class="tocnumber">8.5</span> <span class="toctext">扩展类</span></a></li>
<li class="toclevel-2 tocsection-71"><a href="#.E7.B1.BB.E7.BA.A7.E9.9D.99.E6.80.81.E6.88.90.E5.91.98"><span class="tocnumber">8.6</span> <span class="toctext">类级静态成员</span></a>
<ul>
<li class="toclevel-3 tocsection-72"><a href="#.E9.9D.99.E6.80.81.E6.96.B9.E6.B3.95"><span class="tocnumber">8.6.1</span> <span class="toctext">静态方法</span></a></li>
<li class="toclevel-3 tocsection-73"><a href="#.E9.9D.99.E6.80.81.E5.8F.98.E9.87.8F"><span class="tocnumber">8.6.2</span> <span class="toctext">静态变量</span></a></li>
</ul>
</li>
</ul>
</li>
<li class="toclevel-1 tocsection-74"><a href="#.E6.8E.A5.E5.8F.A3"><span class="tocnumber">9</span> <span class="toctext">接口</span></a>
<ul>
<li class="toclevel-2 tocsection-75"><a href="#.E5.AE.9A.E4.B9.89.E6.8E.A5.E5.8F.A3"><span class="tocnumber">9.1</span> <span class="toctext">定义接口</span></a></li>
<li class="toclevel-2 tocsection-76"><a href="#.E6.8E.A5.E5.8F.A3.E7.9A.84.E5.AE.9E.E7.8E.B0"><span class="tocnumber">9.2</span> <span class="toctext">接口的实现</span></a></li>
<li class="toclevel-2 tocsection-77"><a href="#.E6.89.A9.E5.B1.95.E6.8E.A5.E5.8F.A3"><span class="tocnumber">9.3</span> <span class="toctext">扩展接口</span></a></li>
<li class="toclevel-2 tocsection-78"><a href="#.E5.AE.9A.E4.B9.89.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0.E4.B8.8E.E9.BB.98.E8.AE.A4.E7.B1.BB"><span class="tocnumber">9.4</span> <span class="toctext">定义构造函数与默认类</span></a></li>
<li class="toclevel-2 tocsection-79"><a href="#.E6.8E.A5.E5.8F.A3.E5.B0.8F.E7.BB.93"><span class="tocnumber">9.5</span> <span class="toctext">接口小结</span></a></li>
</ul>
</li>
<li class="toclevel-1 tocsection-80"><a href="#.E6.B3.9B.E5.9E.8B"><span class="tocnumber">10</span> <span class="toctext">泛型</span></a>
<ul>
<li class="toclevel-2 tocsection-81"><a href="#.E4.B8.BA.E4.BD.95.E8.A6.81.E4.BD.BF.E7.94.A8.E6.B3.9B.E5.9E.8B.EF.BC.9F"><span class="tocnumber">10.1</span> <span class="toctext">为何要使用泛型？</span></a></li>
<li class="toclevel-2 tocsection-82"><a href="#.E4.BD.BF.E7.94.A8.E9.9B.86.E5.90.88.E5.B8.B8.E9.87.8F"><span class="tocnumber">10.2</span> <span class="toctext">使用集合常量</span></a></li>
<li class="toclevel-2 tocsection-83"><a href="#.E4.BD.BF.E7.94.A8.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0"><span class="tocnumber">10.3</span> <span class="toctext">使用构造函数</span></a></li>
<li class="toclevel-2 tocsection-84"><a href="#.E6.B3.9B.E9.9B.86.E5.90.88.E5.8F.8A.E5.85.B6.E5.8C.85.E5.90.AB.E7.9A.84.E7.B1.BB.E5.9E.8B"><span class="tocnumber">10.4</span> <span class="toctext">泛集合及其包含的类型</span></a></li>
<li class="toclevel-2 tocsection-85"><a href="#.E6.B3.9B.E5.9E.8B.E5.B0.8F.E7.BB.93"><span class="tocnumber">10.5</span> <span class="toctext">泛型小结</span></a></li>
</ul>
</li>
<li class="toclevel-1 tocsection-86"><a href="#.E5.BA.93.E4.B8.8E.E5.8F.AF.E8.AE.BF.E9.97.AE.E6.80.A7"><span class="tocnumber">11</span> <span class="toctext">库与可访问性</span></a>
<ul>
<li class="toclevel-2 tocsection-87"><a href="#.E4.BD.BF.E7.94.A8.E5.BA.93"><span class="tocnumber">11.1</span> <span class="toctext">使用库</span></a>
<ul>
<li class="toclevel-3 tocsection-88"><a href="#.E6.8C.87.E5.AE.9A.E5.89.8D.E7.BC.80"><span class="tocnumber">11.1.1</span> <span class="toctext">指定前缀</span></a></li>
</ul>
</li>
<li class="toclevel-2 tocsection-89"><a href="#.E5.BA.93.E7.9A.84.E5.AE.9E.E7.8E.B0"><span class="tocnumber">11.2</span> <span class="toctext">库的实现</span></a>
<ul>
<li class="toclevel-3 tocsection-90"><a href="#.E5.B0.86.E6.96.87.E4.BB.B6.E4.B8.8E.E5.BD.93.E5.89.8D.E5.BA.93.E5.85.B3.E8.81.94"><span class="tocnumber">11.2.1</span> <span class="toctext">将文件与当前库关联</span></a></li>
<li class="toclevel-3 tocsection-91"><a href="#.E5.A3.B0.E6.98.8E.E5.BA.93"><span class="tocnumber">11.2.2</span> <span class="toctext">声明库</span></a></li>
<li class="toclevel-3 tocsection-92"><a href="#.E5.A3.B0.E6.98.8E.E7.A7.81.E6.9C.89.E6.88.90.E5.91.98"><span class="tocnumber">11.2.3</span> <span class="toctext">声明私有成员</span></a></li>
</ul>
</li>
<li class="toclevel-2 tocsection-93"><a href="#.E5.BA.93.E4.B8.8E.E5.8F.AF.E8.A7.81.E6.80.A7.E5.B0.8F.E7.BB.93"><span class="tocnumber">11.3</span> <span class="toctext">库与可见性小结</span></a></li>
</ul>
</li>
<li class="toclevel-1 tocsection-94"><a href="#.E9.9A.94.E7.A6.BB"><span class="tocnumber">12</span> <span class="toctext">隔离</span></a>
<ul>
<li class="toclevel-2 tocsection-95"><a href="#.E9.9A.94.E7.A6.BB.E6.A6.82.E5.BF.B5"><span class="tocnumber">12.1</span> <span class="toctext">隔离概念</span></a></li>
<li class="toclevel-2 tocsection-96"><a href="#.E4.BD.BF.E7.94.A8.E9.9A.94.E7.A6.BB"><span class="tocnumber">12.2</span> <span class="toctext">使用隔离</span></a>
<ul>
<li class="toclevel-3 tocsection-97"><a href="#.E5.AF.BC.E5.85.A5_isolate_.E5.BA.93"><span class="tocnumber">12.2.1</span> <span class="toctext">导入 isolate 库</span></a></li>
<li class="toclevel-3 tocsection-98"><a href="#.E5.88.9B.E9.80.A0.E6.96.B0.E9.9A.94.E7.A6.BB"><span class="tocnumber">12.2.2</span> <span class="toctext">创造新隔离</span></a></li>
<li class="toclevel-3 tocsection-99"><a href="#.E5.8F.91.E9.80.81.E6.B6.88.E6.81.AF"><span class="tocnumber">12.2.3</span> <span class="toctext">发送消息</span></a></li>
<li class="toclevel-3 tocsection-100"><a href="#.E5.8F.91.E9.80.81.E4.BB.BB.E6.84.8F.E7.B1.BB.E5.9E.8B.E7.9A.84.E5.AF.B9.E8.B1.A1"><span class="tocnumber">12.2.4</span> <span class="toctext">发送任意类型的对象</span></a></li>
<li class="toclevel-3 tocsection-101"><a href="#.E6.8E.A5.E6.94.B6.E6.B6.88.E6.81.AF"><span class="tocnumber">12.2.5</span> <span class="toctext">接收消息</span></a></li>
<li class="toclevel-3 tocsection-102"><a href="#.E6.8E.A5.E6.94.B6.E5.9B.9E.E5.A4.8D"><span class="tocnumber">12.2.6</span> <span class="toctext">接收回复</span></a></li>
</ul>
</li>
</ul>
</li>
<li class="toclevel-1 tocsection-103"><a href="#.E7.B1.BB.E5.9E.8B.E5.AE.9A.E4.B9.89"><span class="tocnumber">13</span> <span class="toctext">类型定义</span></a></li>
<li class="toclevel-1 tocsection-104"><a href="#.E6.B3.A8.E9.87.8A"><span class="tocnumber">14</span> <span class="toctext">注释</span></a>
<ul>
<li class="toclevel-2 tocsection-105"><a href="#.E5.8D.95.E8.A1.8C.E6.B3.A8.E9.87.8A"><span class="tocnumber">14.1</span> <span class="toctext">单行注释</span></a></li>
<li class="toclevel-2 tocsection-106"><a href="#.E5.A4.9A.E8.A1.8C.E6.B3.A8.E9.87.8A"><span class="tocnumber">14.2</span> <span class="toctext">多行注释</span></a></li>
<li class="toclevel-2 tocsection-107"><a href="#.E6.96.87.E6.A1.A3.E6.B3.A8.E9.87.8A"><span class="tocnumber">14.3</span> <span class="toctext">文档注释</span></a></li>
</ul>
</li>
</ul>
</td></tr></tbody></table>
</td></tr></tbody></table>
<p><span id="main-print"></span>
</p>
<h2> <span class="mw-headline" id=".E5.9F.BA.E6.9C.AC.E7.9A.84_Dart_.E7.A8.8B.E5.BA.8F"> 基本的 Dart 程序 </span></h2>
<p>以下代码
用到了 Dart 最基本的一些功能。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="com">// 变量及取值</span><span class="pln">
  </span><span class="kwd">int</span><span class="pln"> number   </span><span class="pun">=</span><span class="pln"> </span><span class="lit">42</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">String</span><span class="pln"> text     </span><span class="pun">=</span><span class="pln"> </span><span class="str">"number 的数值为"</span><span class="pun">;</span><span class="pln">

  </span><span class="com">// 控制台输出</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"$text $number."</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>下面讲解该程序中大部分 Dart 应用都能用到的部分：
</p>
<h4> <span class="mw-headline" id="main.28.29"> <code>main()</code> </span></h4>
<p>最特别的，<b>必需</b>，
应用开始执行时的顶级函数。
</p>
<h4> <span class="mw-headline" id=".2F.2F"> <code>//</code> </span></h4>
<p>表示该行剩下的部分为<a href="#.E6.B3.A8.E9.87.8A">#注释</a>。
也可以这样写：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="com">/* 可以超过一行的注释内容 */</span></pre>
<h4> <span class="mw-headline" id="int.2C_String"> <code>int, String</code> </span></h4>
<p>通过静态类型说明声明变量。
</p>
<h4> <span class="mw-headline" id=".22....22_.28.E6.88.96_.27....27.29"> <code>"..."</code> (或 <code>'...'</code>) </span></h4>
<p>字符串。
</p>
<h4> <span class="mw-headline" id=".24.E5.8F.98.E9.87.8F.E5.90.8D"> $变量名 </span></h4>
<p>字符串内插字符串或变量的 toString() 值。
</p>
<h4> <span class="mw-headline" id="print.28.29"> <code>print()</code> </span></h4>
<p>显示输出的简便途径。
</p>
<h3> <span class="mw-headline" id=".E6.A0.B7.E5.BC.8F"> 样式 </span></h3>
<p>我们的代码遵循 <a href="/action/edit/Articles/Style_Guide?redlink=1" class="new" title="Articles/Style Guide（尚未撰写）">Dart 样式指南</a>中的约定。
譬如说，约定缩进长度为两个空格。
</p>
<h3> <span class="mw-headline" id=".E8.BF.90.E8.A1.8C.E6.97.B6.E6.A8.A1.E5.BC.8F"> 运行时模式 </span></h3>
<p>Dart 程序可以以生产模式或强制模式运行。
</p><p><em>生产模式（Production mode）</em>是 Dart 程序默认的运行时模式，
为速度而优化。
生产模式下，可选的静态类型会被忽略。
</p><p><em>强制模式（Checked mode）</em>是适合开发者使用的模式，
可帮助您揪出运行过程中的一些类型错误。
例如，如果将非字符串数据赋值给声明为 String 类型的变量，
则会报告异常。
</p><p>我们建议您在强制模式下开发与调试，
而在生产模式下部署。
</p><p><span id="variables"></span>
</p>
<h2> <span class="mw-headline" id=".E5.8F.98.E9.87.8F"> 变量 </span></h2>
<p>下面是创建变量并给其赋值的例子：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Bob'</span><span class="pun">;</span></pre>
<p>变量及引用。名为 <code>name</code> 的变量包含对值为“Bob”的 String 对象的引用。
</p>
<h4> <span class="mw-headline" id=".E9.BB.98.E8.AE.A4.E5.80.BC"> 默认值 </span></h4>
<p>未初始化的变量均有一初始值 <code>null</code>。包括数字类型，属性均为对象。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">num</span><span class="pln"> lineCount</span><span class="pun">;</span><span class="pln">
lineCount </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">;</span><span class="pln"> </span><span class="com">// 表达式结果为 true</span></pre>
<p><br>
</p>
<h4> <span class="mw-headline" id=".E5.8F.AF.E9.80.89.E7.B1.BB.E5.9E.8B"> 可选类型 </span></h4>
<p>您可以选择在变量声明语句中加上静态类型：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="typ">String</span><span class="pln"> name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Bob'</span><span class="pun">;</span></pre>
<p>添加类型名称有助于清晰地表达您的意图。
编译器和编辑器等工具可以利用这些类型声明
提供 bug 预警与代码补全功能。
</p>
<h4> <span class="mw-headline" id="final"> <code>final</code> </span></h4>
<p>如果您不打算改变某个变量的值，可以使用 <code>final</code> 代替<code>var</code>，或者
在类型名称前加上 <code>final</code> 关键字。<code>final</code> 变量一旦赋值，便无法再更改。
</p><p><span class="prettyprint lang-dart linenums:0">
</span></p>
<pre>final String name = 'Bob';
<span class="code-error">name = 'Alice'; // 编译器报错 ERROR (VM 或 JavaScript)</span>
</pre>
<p>
</p>
<h4> <span class="mw-headline" id=".E5.B0.8F.E7.BB.93"> 小结 </span></h4>
<p>Dart 中变量类型可选，尽管我们通常推荐使用类型说明。
变量可以标记为 <code>final</code> 以锁定其值。
未初始化的变量均有初始值 <code>null</code>。
</p><p><span id="built-in-types"></span>
</p>
<h2> <span class="mw-headline" id=".E5.86.85.E7.BD.AE.E7.B1.BB.E5.9E.8B"> 内置类型 </span></h2>
<p>Dart 语言对以下类型提供特别支持：
</p>
<ul><li> <a href="#.E5.AD.97.E7.AC.A6.E4.B8.B2">#字符串</a>
</li><li> <a href="#.E6.95.B0.E5.AD.97">#数字</a>
</li><li> <a href="#.E5.B8.83.E5.B0.94">#布尔</a>
</li><li> <a href="#.E5.88.97.E8.A1.A8">#列表</a>（即 <em>数组</em>）
</li><li> <a href="#.E6.98.A0.E5.B0.84">#映射</a>
</li></ul>
<p>您可以使用<em>常量</em>初始化任一特殊类型对象。
例如，<code>'这是一个字符串'</code> 是字符串常量，
而 <code><b>true</b></code> 是布尔型常量。
</p><p>由于 Dart 中的所有变量均为对象——
某<em>类</em>的一个实例——
您通常可以用<em>构造函数</em>创建变量。
对内置类型的变量也适用。
例如，您可以使用 <code>Map()</code> 构造函数创建映射，
代码为 <code>new Map()</code>。
</p><p><span id="strings"></span>
</p>
<h3> <span class="mw-headline" id=".E5.AD.97.E7.AC.A6.E4.B8.B2"> 字符串 </span></h3>
<p>Dart 中的字符串是一组 Unicode 字符代码的序列。
您可以使用单引号或双引号创建字符串：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var s1 </span><span class="pun">=</span><span class="pln"> </span><span class="str">'单引号可以很好地作为字符串常量。'</span><span class="pun">;</span><span class="pln">
var s2 </span><span class="pun">=</span><span class="pln"> </span><span class="str">"双引号的效果也是一样的。"</span><span class="pun">;</span><span class="pln">
var s3 </span><span class="pun">=</span><span class="pln"> </span><span class="str">'字符串分界符 \' 的转义很方便。'</span><span class="pun">;</span><span class="pln">
var s4 </span><span class="pun">=</span><span class="pln"> </span><span class="str">"使用双引号作为分界符更方便，不用对 ' 进行转义。"</span><span class="pun">;</span></pre>
<p>您可以使用 <code>${<em>表达式</em>}</code> 在字符串中嵌入表达式数值。
如果表达式是变量名称，可以省去 <code>{}</code>。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var s </span><span class="pun">=</span><span class="pln"> </span><span class="str">'内插字符串（string interpolation）'</span><span class="pun">;</span><span class="pln">

print</span><span class="pun">(</span><span class="str">'Dart 的 $s 很方便使用。'</span><span class="pun">);</span><span class="pln">
print</span><span class="pun">(</span><span class="str">'如果需要全部大写，${s.toUpperCase()} 非常方便!'</span><span class="pun">);</span></pre>
<p>您可以将相邻的字符串常量连接为字符串：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var s </span><span class="pun">=</span><span class="pln"> </span><span class="str">'字符串''连接'</span><span class="pln">
        </span><span class="str">"甚至可以跨行进行"</span><span class="pun">;</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">s</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 字符串连接甚至可以跨行进行</span></pre>
<p>另一种创建多行字符串的方法是
使用三个引号，单双皆可。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var s1 </span><span class="pun">=</span><span class="pln"> </span><span class="str">'''</span><span class="pln">
</span><span class="pun">您可以像这样</span><span class="pln">
</span><span class="pun">创建多行字符串。</span><span class="pln">
</span><span class="str">''';</span><span class="pln">

var s2 </span><span class="pun">=</span><span class="pln"> </span><span class="str">"""我也是</span><span class="pln">
</span><span class="pun">多行字符串啊喂。</span><span class="str">""";</span></pre>
<p>您可以在字符串开头加上 <code>@</code> 创建“纯”字符串（译注：即赋值时不转义）。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var s </span><span class="pun">=</span><span class="pln"> </span><span class="pun">@</span><span class="str">'在纯字符串中，连 \n 都会被忽略。'</span><span class="pun">;</span></pre>
<p>与其他所有对象一样，您可以使用 <code><b>==</b></code> 运算符检查两个字符串是否等价（字符全部相同）：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'NAME'</span><span class="pun">;</span><span class="pln">
var greeting </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Hello, $name!"</span><span class="pun">;</span><span class="pln">
var greetingTemplate </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Hello, NAME!'</span><span class="pun">;</span><span class="pln">

print</span><span class="pun">(</span><span class="pln">greeting </span><span class="pun">==</span><span class="pln"> greetingTemplate</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 输出 true；字符完全相同</span></pre>
<p><span id="strings-string"></span>
</p>
<h4> <span class="mw-headline" id=".E5.AD.97.E7.AC.A6.E4.B8.B2.E6.96.B9.E6.B3.95"> 字符串方法 </span></h4>
<p>所有字符串常量的类型均为 <a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/String.html">String</a>。
<code>String</code> 有一些实用方法，包括比较等功能。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var fullName </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Cuthbert Musgrave Girdlestone, III'</span><span class="pun">;</span><span class="pln">

fullName</span><span class="pun">.</span><span class="pln">startsWith</span><span class="pun">(</span><span class="str">'Cuthbert'</span><span class="pun">);</span><span class="pln">            </span><span class="com">// true；以“Cuthbert”开头</span><span class="pln">
fullName</span><span class="pun">.</span><span class="pln">endsWith</span><span class="pun">(</span><span class="str">'III'</span><span class="pun">);</span><span class="pln">                   </span><span class="com">// true；以“III”结尾</span><span class="pln">
fullName</span><span class="pun">.</span><span class="pln">contains</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">RegExp</span><span class="pun">(</span><span class="str">'Musgrave'</span><span class="pun">));</span><span class="pln">  </span><span class="com">// true；匹配正则表达式“/Musgrave/”</span></pre>
<p>字符串对象无法改变（immutable），
即只能创建，但不能修改。
如果您仔细阅读
<a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/String.html">String API 文档</a>
会发现，所有方法都不会
真正地改变 <code>String</code> 类型的状态。
例如，<code>replaceAll()</code> 方法只返回新的 <code>String</code> 对象，
而没有改变原来的 <code>String</code> 对象。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var greetingTemplate </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Hello, NAME!'</span><span class="pun">;</span><span class="pln">
var greeting </span><span class="pun">=</span><span class="pln"> greetingTemplate</span><span class="pun">.</span><span class="pln">replaceAll</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">RegExp</span><span class="pun">(</span><span class="str">"NAME"</span><span class="pun">),</span><span class="pln"> </span><span class="str">'Bob'</span><span class="pun">);</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">greeting </span><span class="pun">==</span><span class="pln"> greetingTemplate</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 输出 false；greetingTemplate 没有变化</span></pre>
<p><span id="strings-buffer"></span>
</p>
<h4> <span class="mw-headline" id="StringBuffer_.E6.96.B9.E6.B3.95"> StringBuffer 方法 </span></h4>
<p>要通过程序生成字符串，您可以使用 <code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/StringBuffer.html">StringBuffer</a></code>。
<code>StringBuffer</code> 在调用 <code>toString()</code> 之前不会生成新的 <code>String</code> 对象。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var sb </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StringBuffer</span><span class="pun">();</span><span class="pln">

sb</span><span class="pun">.</span><span class="pln">add</span><span class="pun">(</span><span class="str">"使用 StringBuffer"</span><span class="pun">);</span><span class="pln">
sb</span><span class="pun">.</span><span class="pln">addAll</span><span class="pun">([</span><span class="str">" 可"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"高效"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"创建"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"字符串，"</span><span class="pun">]);</span><span class="pln">
sb</span><span class="pun">.</span><span class="pln">add</span><span class="pun">(</span><span class="str">"数量越多 "</span><span class="pun">).</span><span class="pln">add</span><span class="pun">(</span><span class="str">"效果越明显。"</span><span class="pun">);</span><span class="pln">

var fullString </span><span class="pun">=</span><span class="pln"> sb</span><span class="pun">.</span><span class="pln">toString</span><span class="pun">();</span><span class="pln">

print</span><span class="pun">(</span><span class="pln">fullString</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 使用 StringBuffer 可高效创建字符串，</span><span class="pln">
                   </span><span class="com">// 数量越多 效果越明显。</span><span class="pln">

sb</span><span class="pun">.</span><span class="pln">clear</span><span class="pun">();</span><span class="pln">        </span><span class="com">// 清空对象！</span></pre>
<p><br>
</p>
<div class="note">
<p><b>注：</b>
目前，编译为 JavaScript 代码后 StringBuffer 执行很慢。
详情请见 bug #<a rel="nofollow" class="external text" href="http://code.google.com/p/dart/issues/detail?id=1216">1216</a>
。
</p>
</div>
<p><span id="numbers"></span>
</p>
<h3> <span class="mw-headline" id=".E6.95.B0.E5.AD.97"> 数字 </span></h3>
<p>Dart 中的数字分为两种：
</p>
<h5> <span class="mw-headline" id="int"> <code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/int.html">int</a></code> </span></h5>
<p>任意大小的整数
</p>
<h5> <span class="mw-headline" id="double"> <code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/double.html">double</a></code> </span></h5>
<p>十进制 64 位双精度浮点数，遵循 IEEE 754 规范所约定的格式
</p><p><code><b>int</b></code> 和 <code><b>double</b></code> 都是 <code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/num.html">num</a></code> 的子接口。
<code>num</code> 接口定义了基本的运算符，如 <code>+</code>、<code>-</code>、<code>/</code> 和 <code>*</code>，
以及位运算符，如 <code>&gt;&gt;</code>。
</p><p><code>num</code> 接口中还有 <code>abs()</code>、<code>ceil()</code>、<code>floor()</code> 等方法。
如果 <code>num</code> 及其子接口中没有您需要的功能，
<a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Math.html">Math</a> 类中可能会有所提供。
</p><p>整数是没有小数点的数字。
下面是一些定义整数常量的例子：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var x </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span><span class="pln">
var hex </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0xDEADBEEF</span><span class="pun">;</span><span class="pln">
var bigInt </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3465346583465243765923847659234765928347659567398475647495873984572947593470294387093493456870849216348723763945678236420938467345762304958724596873045876234572037862934765294365243652548673456705673465273465246734506873456729457623845623456234650457693475603768922346728346256</span><span class="pun">;</span></pre>
<p>如果数字含有小数点，
则为双精度浮点数。
以下是一些定义双精度浮点数常量的例子：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var y </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1.1</span><span class="pun">;</span><span class="pln">
var exponents </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1.42e5</span><span class="pun">;</span></pre>
<p>下例展示如何在字符串和数字类型之间进行相互转换：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="com">// string -&gt; int</span><span class="pln">
var one </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Math</span><span class="pun">.</span><span class="pln">parseInt</span><span class="pun">(</span><span class="str">"1"</span><span class="pun">);</span><span class="pln">                   </span><span class="com">// 1</span><span class="pln">

</span><span class="com">// string -&gt; double</span><span class="pln">
var onePointOne </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Math</span><span class="pun">.</span><span class="pln">parseDouble</span><span class="pun">(</span><span class="str">"1.1"</span><span class="pun">);</span><span class="pln">      </span><span class="com">// 1.1</span><span class="pln">

</span><span class="com">// int -&gt; string</span><span class="pln">
</span><span class="typ">String</span><span class="pln"> oneAsString </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1.toString</span><span class="pun">();</span><span class="pln">              </span><span class="com">// "1"</span><span class="pln">

</span><span class="com">// double -&gt; string</span><span class="pln">
</span><span class="typ">String</span><span class="pln"> piAsString </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3.14159</span><span class="pun">.</span><span class="pln">toStringAsFixed</span><span class="pun">(</span><span class="lit">2</span><span class="pun">);</span><span class="pln"> </span><span class="com">// "3.14"</span></pre>
<p><span id="booleans"></span>
</p>
<h3> <span class="mw-headline" id=".E5.B8.83.E5.B0.94"> 布尔 </span></h3>
<p>Dart 有正式的布尔类型，名为 <code><b>bool</b></code>。
只有两种对象的类型为 <code>bool</code>：
布尔常量，<code><b>true</b></code> 和 <code><b>false</b></code>。
</p><p>当 Dart 需要一个布尔值时，
如果该值不是 <code><b>true</b></code>，
那就肯定是 <code><b>false</b></code>。
不像在 JavaScript 中
<code>1</code> 或非 <code>null</code> 对象不作为 <code>true</code> 对待。
</p><p>例如，对于下述的代码：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Bob'</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">name</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"你有名字耶！"</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 在 JavaScript 中可以输出，但 Dart 中不能</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>在 JavaScript 环境，该段代码会输出“你有名字耶！”，因为
<code>name</code> 是非 <code>null</code> 对象。
但在 Dart 中，这段代码不会输出任何内容，
因为 <code>name</code> 被作为 <code><b>false</b></code> 对待
（表达式 <code>name&nbsp;!= true</code> 成立）。
</p><p>下面是另一段 JavaScript 与 Dart 表现截然不同的示例代码：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"JavaScript 会输出本行，因为它认为 1 等于 true。"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"Dart 会输出本行，因为它认为 1 *不* 等于 true。"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><br>
</p>
<div class="note">
<p><b>注：</b>
Dart 实验室目前对上述两例的表现有误，
它会输出 JavaScript 的执行结果。
（详情请见 bug #<a rel="nofollow" class="external text" href="http://code.google.com/p/dart/issues/detail?id=1190">1190</a>。）
还需要注意的是，
与本文其余示例代码不同，
上述两例不能在强制模式下执行。
</p>
</div>
<p>Dart 对布尔值的处理方式
是为了避免很多值被作为 <code>true</code> 对待
所引发的诸多奇怪现象。
对您而言，
应避免使用
<code>if&nbsp;(<em>非布尔值</em>)</code> 这样的代码，
而应该对值进行显式检查。
例如：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="com">// 检查空字符串</span><span class="pln">
var fullName </span><span class="pun">=</span><span class="pln"> </span><span class="str">''</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">fullName</span><span class="pun">.</span><span class="pln">isEmpty</span><span class="pun">())</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"请输入姓名"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="com">// 检查零分</span><span class="pln">
var hitPoints </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">hitPoints </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"啊呃！你好像挂掉了哎。"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="com">// 检查 null</span><span class="pln">
var unicorn </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">unicorn </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"许愿不够给力。再加点油！"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="com">// 检查 NaN</span><span class="pln">
var iMeantToDoThis </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">/</span><span class="lit">0</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">iMeantToDoThis</span><span class="pun">.</span><span class="pln">isNaN</span><span class="pun">())</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"0/0 不是数字。"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><span id=".E5.88.97.E8.A1.A8"></span><span id="lists"></span>
</p>
<h3> <span class="mw-headline" id=".E5.88.97.E8.A1.A8.EF.BC.88.E5.8D.B3.E6.95.B0.E7.BB.84.EF.BC.89"> 列表（即数组） </span></h3>
<p>几乎所有编程语言中都有的最常见的集合或许就是
<em>数组</em> 了——或者称之为有顺序的对象集合。
在 Dart 中，数组属于 <code>List</code> 类型的对象，
因此我们通常称之为 <em>列表</em>。
当您将 Dart 编译为 JavaScript 脚本时，
Dart 列表会被编译为 JavaScript 数组。
</p><p>Dart 列表常量与 JavaScript 数组常量一样。
这是一个简单的 Dart 列表：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var list </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="lit">2</span><span class="pun">,</span><span class="lit">3</span><span class="pun">];</span></pre>
<p>您可以获取列表的长度
以及引用列表元素，
语法与 JavaScript 相同：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var list </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="lit">2</span><span class="pun">,</span><span class="lit">3</span><span class="pun">];</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">list</span><span class="pun">.</span><span class="pln">length</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 元素数目：3</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">list</span><span class="pun">[</span><span class="lit">1</span><span class="pun">]);</span><span class="pln">     </span><span class="com">// 第二项：2</span></pre>
<p>您可以使用 <code><b>add()</b></code> 方法将元素添加到列表：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var list </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="lit">2</span><span class="pun">,</span><span class="lit">3</span><span class="pun">];</span><span class="pln">
list</span><span class="pun">.</span><span class="pln">add</span><span class="pun">(</span><span class="lit">4</span><span class="pun">);</span></pre>
<p>要将元素从列表移除
（减短列表长度），
请使用 <code><b>removeRange()</b></code> 方法：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var list </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="lit">2</span><span class="pun">,</span><span class="lit">3</span><span class="pun">,</span><span class="lit">4</span><span class="pun">];</span><span class="pln">
list</span><span class="pun">.</span><span class="pln">removeRange</span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 移除第三个元素</span></pre>
<p><span id="list-iterate"></span>
</p>
<h4> <span class="mw-headline" id=".E9.81.8D.E5.8E.86"> 遍历 </span></h4>
<p>如果需要处理列表的每一个元素，
您可以使用 <code><b>for</b></code>、<code><b>for</b>...<b>in</b></code> 或 <code><b>forEach()</b></code>。
如果需要当前遍历到的索引编号，请使用 <code><b>for</b></code> 语句：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var list </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="lit">2</span><span class="pun">,</span><span class="lit">3</span><span class="pun">];</span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="pln">var x </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> x </span><span class="pun">&lt;</span><span class="pln"> list</span><span class="pun">.</span><span class="pln">length</span><span class="pun">;</span><span class="pln"> x</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">'$x: ${list[x]}'</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>如果不需要索引编号，
可以使用 <code><b>for</b>...<b>in</b></code> 语句：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var list </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="lit">2</span><span class="pun">,</span><span class="lit">3</span><span class="pun">];</span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">final</span><span class="pln"> x in list</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">x</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>如果只是想对列表各元素应用某个函数，
请使用 <code><b>forEach()</b></code> 方法：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var list </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="lit">2</span><span class="pun">,</span><span class="lit">3</span><span class="pun">];</span><span class="pln">
</span><span class="kwd">void</span><span class="pln"> printElement</span><span class="pun">(</span><span class="pln">element</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> print</span><span class="pun">(</span><span class="pln">element</span><span class="pun">);</span><span class="pln">
list</span><span class="pun">.</span><span class="pln">forEach</span><span class="pun">(</span><span class="pln">printElement</span><span class="pun">);</span></pre>
<p>或者更简洁地：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var list </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="lit">2</span><span class="pun">,</span><span class="lit">3</span><span class="pun">];</span><span class="pln">
list</span><span class="pun">.</span><span class="pln">forEach</span><span class="pun">((</span><span class="pln">element</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> print</span><span class="pun">(</span><span class="pln">element</span><span class="pun">));</span></pre>
<p><span id="list-collection"></span>
</p>
<h4> <span class="mw-headline" id=".E5.88.97.E8.A1.A8.E4.B8.8E.E9.9B.86.E5.90.88.E6.96.B9.E6.B3.95"> 列表与集合方法 </span></h4>
<p><code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Collection.html#forEach">forEach()</a></code> 方法
是
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/List.html">List</a></code>
接口及其超接口
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Collection.html">Collection</a></code>
所定义的诸多实用方法之一。
其他还有如：
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Collection.html#filter">filter()</a></code> 方法
可返回新的集合，只包含满足特定条件的元素。
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Collection.html#every">every()</a></code> 与
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Collection.html#some">some()</a></code> 方法
分别可用来检查集合是否匹配
所有条件或至少一个条件。
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/List.html#sort">sort()</a></code> 方法
允许按任意需要的条件对列表进行排序。
</p><p>关于列表的更多信息请见 <a href="#.E6.B3.9B.E5.9E.8B">#泛型</a>。
</p><p><span id="maps"></span>
</p>
<h3> <span class="mw-headline" id=".E6.98.A0.E5.B0.84"> 映射 </span></h3>
<p>总的来说，映射是包含键值对应关系的对象。
Dart 对映射的支持是通过映射常量以及
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Map.html">Map</a></code> 接口实现的。
</p><p>下面是简单 Dart 映射的例子：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var gifts </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln">     </span><span class="com">// 映射常量</span><span class="pln">
</span><span class="com">// 键       值</span><span class="pln">
  </span><span class="str">"第一天"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"山鹑"</span><span class="pun">,</span><span class="pln">
  </span><span class="str">"第二天"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"斑鸠"</span><span class="pun">,</span><span class="pln">
  </span><span class="str">"第五天"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"环颈雉"</span><span class="pun">};</span></pre>
<p>在映射常量中，每个 <b>键</b> 必须为字符串。
如果您使用 <code>Map</code> 的构造函数，
还有其他选择：
键可以是字符串、数字或其他任意实现了
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Hashable.html">Hashable</a></code>
接口的对象。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var map </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Map</span><span class="pun">();</span><span class="pln">   </span><span class="com">// 使用 Map 构造函数</span><span class="pln">
map</span><span class="pun">[</span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"山鹑"</span><span class="pun">;</span><span class="pln">       </span><span class="com">// 键为 1；值为“山鹑”</span><span class="pln">
map</span><span class="pun">[</span><span class="lit">2</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"斑鸠"</span><span class="pun">;</span><span class="pln">       </span><span class="com">// 键为 2；值为“斑鸠”</span><span class="pln">
map</span><span class="pun">[</span><span class="lit">5</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"环颈雉"</span><span class="pun">;</span><span class="pln">     </span><span class="com">// 键为 5；值为“环颈雉”</span></pre>
<p>映射中的 <b>值</b> 可以是任意对象或 <code>null</code>。
</p><p>将新的键值对添加到现有映射中的方法
与 JavaScript 中无异：
</p><p><span class="prettyprint lang-dart linenums:0">
</span></p>
<pre>var gifts = { "第一天": "山鹑" };
<b>gifts["第四天"] = "乌鸫";</b>   // 添加一组键值对
</pre>
<p>
</p><p>从映射中提取值的方法也和 JavaScript 中一样：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var gifts </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="str">"第一天"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"山鹑"</span><span class="pln"> </span><span class="pun">};</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">gifts</span><span class="pun">[</span><span class="str">'第一天'</span><span class="pun">]);</span><span class="pln">        </span><span class="com">// 山鹑</span></pre>
<p>如果您查找的键在映射中不存在，
将在返回中得到 <code>null</code>。
不过，由于值可以为 <code>null</code>，
您可能需要使用
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Map.html#containsKey">containsKey()</a></code> 或
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Map.html#putIfAbsent">putIfAbsent()</a></code>
等方法获知 <code>null</code> 的确切情况。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var gifts </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="str">"第一天"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"山鹑"</span><span class="pln"> </span><span class="pun">};</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">gifts</span><span class="pun">[</span><span class="str">'第五天'</span><span class="pun">]);</span><span class="pln">        </span><span class="com">// null</span></pre>
<p>使用 <code><b>.length</b></code> 可以获取映射中键值对的数目：
</p><p><span class="prettyprint lang-dart linenums:0">
</span></p>
<pre>var gifts = { "第一天": "山鹑" };
gifts["第四天"] = "乌鸫";
print(<b>gifts.length</b>);         // 2
</pre>
<p>
</p><p>要从映射中移除键值对，
可以使用 <code><b>remove()</b></code> 方法：
</p><p><span class="prettyprint lang-dart linenums:0">
</span></p>
<pre>var gifts = { "第一天": "山鹑" };
gifts["第四天"] = "乌鸫";
<b>gifts.remove('第一天');</b>
print(gifts.length);           // 1
print(gifts['第一天']);        // null
</pre>
<p>
</p><p>您可以使用 <code><b>Map.from()</b></code> 构造函数复制映射：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var gifts </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="str">"第一天"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"山鹑"</span><span class="pln"> </span><span class="pun">};</span><span class="pln">
var regifts </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Map</span><span class="pun">.</span><span class="pln">from</span><span class="pun">(</span><span class="pln">gifts</span><span class="pun">);</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">regifts</span><span class="pun">[</span><span class="str">'第一天'</span><span class="pun">]);</span><span class="pln">      </span><span class="com">// 山鹑</span></pre>
<p><span id="maps-iterating"></span>
</p>
<h4> <span class="mw-headline" id=".E9.81.8D.E5.8E.86_2"> 遍历 </span></h4>
<p>遍历映射的内容有几种方法。
使用 <code><b>forEach()</b></code> 方法
可同时访问键值。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var gifts </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="str">"第一天"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"山鹑"</span><span class="pun">,</span><span class="pln">
  </span><span class="str">"第二天"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"斑鸠"</span><span class="pun">,</span><span class="pln">
  </span><span class="str">"第五天"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"环颈雉"</span><span class="pun">};</span><span class="pln">
gifts</span><span class="pun">.</span><span class="pln">forEach</span><span class="pun">((</span><span class="pln">k</span><span class="pun">,</span><span class="pln">v</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> print</span><span class="pun">(</span><span class="str">'$k：$v'</span><span class="pun">));</span></pre>
<div class="note">
<p><b>注：</b>
不要指望 <code>forEach()</code> 
按特定顺序返回键值对。
</p>
</div>
<p>如果您只对键或值感兴趣，
可以分别使用 <code><b>getKeys()</b></code> 或 <code><b>getValues()</b></code>。
两种方法均可返回
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Collection.html">Collection</a></code> 对象。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var gifts </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="str">"第一天"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"山鹑"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"第二天"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"斑鸠"</span><span class="pun">};</span><span class="pln">
var values </span><span class="pun">=</span><span class="pln"> gifts</span><span class="pun">.</span><span class="pln">getValues</span><span class="pun">();</span><span class="pln">
values</span><span class="pun">.</span><span class="pln">forEach</span><span class="pun">((</span><span class="pln">v</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> print</span><span class="pun">(</span><span class="pln">v</span><span class="pun">));</span><span class="pln">      </span><span class="com">// 山鹑, 斑鸠</span></pre>
<div class="note">
<p><b>注：</b>
映射对象本身不会扩展到 <code>Collection</code> 接口。
</p>
</div>
<p><span id="builtin-summary"></span>
</p>
<h3> <span class="mw-headline" id=".E5.86.85.E7.BD.AE.E7.B1.BB.E5.9E.8B.E5.B0.8F.E7.BB.93"> 内置类型小结 </span></h3>
<p>Dart 的 <a href="#.E5.86.85.E7.BD.AE.E7.B1.BB.E5.9E.8B">#内置类型</a> 均有
特别的常量格式，并实现了内置接口。
例如，数字常量如
<code>1</code> 和
<code>1.1</code>，
它们实现了 <code>num</code> 接口。
</p><p>您通常会用常量创建大多数内置类型对象，
但也可以用构造函数。
布尔类型有所不同，因为您无法创建类型为
<code>bool</code> 的新对象；
只能用 <code>true</code> 与 <code>false</code> 实现。
</p><p>关于映射与列表的详细信息，
请参见 <a href="#.E6.B3.9B.E5.9E.8B">#泛型</a>。
</p><p><span id="functions"></span>
</p>
<h2> <span class="mw-headline" id=".E5.87.BD.E6.95.B0"> 函数 </span></h2>
<p>下面是一个简单的函数：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="typ">String</span><span class="pln"> say</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> from</span><span class="pun">,</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> msg</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="str">"$from 说“$msg”"</span><span class="pun">;</span></pre>
<p>下面是调用该函数的示例：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">print</span><span class="pun">(</span><span class="pln">say</span><span class="pun">(</span><span class="str">"Bob"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Hello"</span><span class="pun">));</span><span class="pln"> </span><span class="com">// "Bob 说“Hello”"</span></pre>
<p>若忽略类型，上面的代码也可以这样写：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">say</span><span class="pun">(</span><span class="pln">from</span><span class="pun">,</span><span class="pln"> msg</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="str">"$from 说“$msg”"</span><span class="pun">;</span></pre>
<p>不过，我们推荐在函数签名处说明参数类型。
</p><p><code>=&gt; e;</code> 语法是 <code>{ return e; }</code> 的简写式。
如 <code>say(from, msg) =&gt; "$from 说“$msg”";</code>
与下面的写法等效：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">say</span><span class="pun">(</span><span class="pln">from</span><span class="pun">,</span><span class="pln"> msg</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> </span><span class="str">"$from 说“$msg”"</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>
<h4> <span class="mw-headline" id=".E5.8F.AF.E9.80.89.E5.8F.82.E6.95.B0"> 可选参数 </span></h4>
<p>将函数参数放在 <code>[]</code> 括号内可将其标记为可选参数。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="typ">String</span><span class="pln"> say</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> from</span><span class="pun">,</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> msg</span><span class="pun">,</span><span class="pln"> </span><span class="pun">[</span><span class="typ">String</span><span class="pln"> device</span><span class="pun">])</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  var result </span><span class="pun">=</span><span class="pln"> </span><span class="str">"$from 说“$msg”"</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">device&nbsp;</span><span class="pun">!=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    result </span><span class="pun">=</span><span class="pln"> </span><span class="str">"$result（通过 $device 发送）"</span><span class="pun">;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> result</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>下面是调用时不提供可选参数的例子：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">print</span><span class="pun">(</span><span class="pln">say</span><span class="pun">(</span><span class="str">"Bob"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"你好呀"</span><span class="pun">));</span><span class="pln"> </span><span class="com">// Bob 说“你好呀”</span></pre>
<p>下面是提供第三个参数调用该函数时的例子：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">print</span><span class="pun">(</span><span class="pln">say</span><span class="pun">(</span><span class="str">"Bob"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"你好呀"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"狼烟"</span><span class="pun">));</span><span class="pln">
</span><span class="com">// Bob 说“你好呀”（通过 狼烟 发送）</span></pre>
<h4> <span class="mw-headline" id=".E5.8F.AF.E9.80.89.E5.8F.82.E6.95.B0.E7.9A.84.E9.BB.98.E8.AE.A4.E5.80.BC"> 可选参数的默认值 </span></h4>
<p>您可以给可选参数指定默认值。默认值必须为编译时常量。
如果没有提供默认值，其值则为 <code>null</code>（上例即是）。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="typ">String</span><span class="pln"> say</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> from</span><span class="pun">,</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> msg</span><span class="pun">,</span><span class="pln"> </span><span class="pun">[</span><span class="typ">String</span><span class="pln"> device</span><span class="pun">=</span><span class="str">'信鸽'</span><span class="pun">])</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  var result </span><span class="pun">=</span><span class="pln"> </span><span class="str">"$from 说“$msg”"</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">device&nbsp;</span><span class="pun">!=</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    result </span><span class="pun">=</span><span class="pln"> </span><span class="str">"$result（通过 $device 发送）"</span><span class="pun">;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> result</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>如果省去可选参数，则会使用默认值：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">print</span><span class="pun">(</span><span class="pln">say</span><span class="pun">(</span><span class="str">"Bob"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"你好呀"</span><span class="pun">));</span><span class="pln"> </span><span class="com">// Bob 说“你好呀”（通过 信鸽 发送）</span></pre>
<h4> <span class="mw-headline" id=".E5.91.BD.E5.90.8D.E5.8F.82.E6.95.B0"> 命名参数 </span></h4>
<p>可选参数同时也是命名参数。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">print</span><span class="pun">(</span><span class="pln">say</span><span class="pun">(</span><span class="str">"Bob"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"你好呀"</span><span class="pun">,</span><span class="pln"> device</span><span class="pun">:</span><span class="pln"> </span><span class="str">"易拉罐话筒"</span><span class="pun">));</span><span class="pln">
</span><span class="com">// Bob 说“你好呀”（通过 易拉罐话筒 发送）</span></pre>
<h4> <span class="mw-headline" id=".E7.AC.AC.E4.B8.80.E7.B1.BB.E5.87.BD.E6.95.B0"> 第一类函数 </span></h4>
<p>您可以将函数作为参数传递给其他函数。例如：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="typ">List</span><span class="pln"> ages </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="lit">4</span><span class="pun">,</span><span class="lit">5</span><span class="pun">,</span><span class="lit">7</span><span class="pun">,</span><span class="lit">10</span><span class="pun">,</span><span class="lit">14</span><span class="pun">,</span><span class="lit">21</span><span class="pun">];</span><span class="pln">
</span><span class="typ">List</span><span class="pln"> oddAges </span><span class="pun">=</span><span class="pln"> ages</span><span class="pun">.</span><span class="pln">filter</span><span class="pun">((</span><span class="pln">i</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> i&nbsp;</span><span class="pun">%</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span></pre>
<p>与下面的代码等效：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">bool isOdd</span><span class="pun">(</span><span class="kwd">num</span><span class="pln"> i</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> i&nbsp;</span><span class="pun">%</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span><span class="pln">
</span><span class="typ">List</span><span class="pln"> ages </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="lit">4</span><span class="pun">,</span><span class="lit">5</span><span class="pun">,</span><span class="lit">7</span><span class="pun">,</span><span class="lit">10</span><span class="pun">,</span><span class="lit">14</span><span class="pun">,</span><span class="lit">21</span><span class="pun">];</span><span class="pln">
</span><span class="typ">List</span><span class="pln"> oddAges </span><span class="pun">=</span><span class="pln"> ages</span><span class="pun">.</span><span class="pln">filter</span><span class="pun">(</span><span class="pln">isOdd</span><span class="pun">);</span></pre>
<p>您也可以将函数赋值给变量，如：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var loudify </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">msg</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="str">'!!! ${msg.toUpperCase()}&nbsp;!!!'</span><span class="pun">;</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">loudify</span><span class="pun">(</span><span class="str">'hello'</span><span class="pun">));</span></pre>
<h4> <span class="mw-headline" id=".E8.AF.8D.E6.B3.95.E5.B0.81.E8.A3.85"> 词法封装 </span></h4>
<p>函数可将周边区域定义的变量进行封装处理。
下例展示 <code>makeAdder</code> 函数如何捕获变量 <code>n</code>
并将其传递给 <code>makeAdder</code> 所返回的函数。
不论所返回的函数在哪里调用，它都能捕获变量 <code>n</code>。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="typ">Function</span><span class="pln"> makeAdder</span><span class="pun">(</span><span class="kwd">num</span><span class="pln"> n</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">num</span><span class="pln"> i</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> n </span><span class="pun">+</span><span class="pln"> i</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  var add2 </span><span class="pun">=</span><span class="pln"> makeAdder</span><span class="pun">(</span><span class="lit">2</span><span class="pun">);</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">add2</span><span class="pun">(</span><span class="lit">3</span><span class="pun">));</span><span class="pln"> </span><span class="com">// 5</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>（特别感谢 Bob Nystrom 提供本例。）
</p>
<h4> <span class="mw-headline" id=".E8.BF.94.E5.9B.9E.E5.80.BC"> 返回值 </span></h4>
<p>所有函数都会返回一个值。如果未指定返回值，则将在函数主体的末端隐式调用 <code>return null;</code> 语句。
</p>
<h3> <span class="mw-headline" id=".E5.87.BD.E6.95.B0.E5.B0.8F.E7.BB.93"> 函数小结 </span></h3>
<p>Dart 支持第一类函数，以及可选参数、命名参数和参数默认值。
函数可被赋值给变量，或作为参数传递给其他函数。
函数还支持词法封装，可访问其直接词域以外的变量。
</p><p><span id="operators"></span>
</p>
<h2> <span class="mw-headline" id=".E8.BF.90.E7.AE.97.E7.AC.A6"> 运算符 </span></h2>
<p>Dart 支持运算符。
它不仅定义运算符，
还允许您重新定义其中很多运算符。
</p><p>下表按优先级顺序
列出了 Dart 的全部运算符。
</p>
<table class="operatorTable">
<tbody><tr>
<th>描述</th>
<th>运算符</th>
<th>结合性</th>
</tr>

<tr>
<td>一元后缀</td>
<td class="operatorList"><code><em>表达式</em>++ <em>表达式</em>-- () [] .</code></td>
<td>左</td>
</tr>

<tr>
<td>一元前缀</td>
<td class="operatorList"><code>-<em>表达式</em>&nbsp;!<em>表达式</em> ~<em>表达式</em> ++<em>表达式</em> --<em>表达式</em></code></td>
<td>右</td>
</tr>

<tr>
<td>乘除</td>
<td class="operatorList"><code>* /&nbsp;% ~/</code></td>
<td>左</td>
</tr>

<tr>
<td>加减</td>
<td class="operatorList"><code>+ -</code></td>
<td>左</td>
</tr>

<tr>
<td>移位</td>
<td class="operatorList"><code>&lt;&lt; &gt;&gt;</code></td>
<td>左</td>
</tr>

<tr>
<td>关系</td>
<td class="operatorList"><code>is is! &gt;= &gt; &lt;= &lt;</code></td>
<td>无</td>
</tr>

<tr>
<td>相等性</td>
<td class="operatorList"><code>==&nbsp;!= ===&nbsp;!==</code></td>
<td>无</td>
</tr>

<tr>
<td>位 AND</td>
<td class="operatorList"><code>&amp;</code></td>
<td>左</td>
</tr>

<tr>
<td>位 XOR</td>
<td class="operatorList"><code>^</code></td>
<td>左</td>
</tr>

<tr>
<td>位 OR</td>
<td class="operatorList"><code>|</code></td>
<td>左</td>
</tr>

<tr>
<td>逻辑 AND</td>
<td class="operatorList"><code>&amp;&amp;</code></td>
<td>左</td>
</tr>

<tr>
<td>逻辑 OR</td>
<td class="operatorList"><code>||</code></td>
<td>左</td>
</tr>

<tr>
<td>条件</td>
<td class="operatorList"><code><em>表达式</em>&nbsp;? <em>表达式</em>&nbsp;: <em>表达式</em></code></td>
<td>无</td>
</tr>

<tr>
<td>赋值</td>
<td class="operatorList"><code>= *= /= ~/=&nbsp;%= += -= &lt;&lt;= &gt;&gt;= &amp;= ^= |=</code> </td>
<td>右</td>
</tr>
</tbody></table>
<p><br>
例如， <code><b>%</b></code> 运算符的优先级
高于
<code><b>==</b></code> 运算符，因此在其之前执行；
而 <code><b>==</b></code> 的优先级又高于 <b>&amp;&amp;</b> 运算符。
这种优先顺序意味着
下面两行代码是等价执行的：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">if</span><span class="pln"> </span><span class="pun">((</span><span class="pln">n&nbsp;</span><span class="pun">%</span><span class="pln"> i </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&amp;&amp;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">d&nbsp;</span><span class="pun">%</span><span class="pln"> i </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">))</span><span class="pln"> </span><span class="com">// 括号可增强可读性</span><span class="pln">
</span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">n&nbsp;</span><span class="pun">%</span><span class="pln"> i </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="pun">&amp;&amp;</span><span class="pln"> d&nbsp;</span><span class="pun">%</span><span class="pln"> i </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln">     </span><span class="com">// 难以阅读，但与上一行等价</span></pre>
<p>本段落将涉及下述主题：
</p>
<ul><li> <a href="#op-arithmetic">算术运算符</a>
</li><li> <a href="#op-equality">相等性与关系运算符</a>
</li><li> <a href="#op-assign">赋值运算符</a>
</li><li> <a href="#op-logical">逻辑运算符</a>
</li><li> <a href="#op-bit">位操作与移位运算符</a>
</li><li> <a href="#op-other">其他运算符</a>
</li><li> <a href="#op-methods">运算符作为方法调用</a>
</li></ul>
<p><span id="op-arithmetic"></span>
</p>
<h3> <span class="mw-headline" id=".E7.AE.97.E6.9C.AF.E8.BF.90.E7.AE.97.E7.AC.A6"> 算术运算符 </span></h3>
<p>Dart 支持常用的算术运算符。
</p>
<table class="operatorTable">
  <tbody><tr> <th> 运算符 </th> <th> 定义 </th> </tr>
  <tr>
    <td class="operator"> <code>+</code> </td>  <td> 加 </td>
  </tr><tr>
    <td class="operator"> <code>–</code> </td>  <td> 减 </td>
  </tr><tr>
    <td class="operator"> <code>-<em>表达式</em></code> </td>
    <td> 一元否定（令表达式符号取反） </td>
  </tr><tr>
    <td class="operator"> <code>*</code> </td>  <td> 乘 </td>
  </tr><tr>
    <td class="operator"> <code>/</code> </td>  <td> 除 </td>
  </tr><tr>
    <td class="operator"> <code>~/</code> </td> <td> 除，返回结果的整数部分 </td>
  </tr><tr>
    <td class="operator"> <code>%</code> </td>  <td> 求余 </td>
  </tr>
</tbody></table>
<p>例：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">int</span><span class="pln"> a </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> b </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3</span><span class="pun">;</span><span class="pln">

print</span><span class="pun">(</span><span class="str">'${a + b}'</span><span class="pun">);</span><span class="pln">  </span><span class="com">// 5</span><span class="pln">
print</span><span class="pun">(</span><span class="str">'${a - b}'</span><span class="pun">);</span><span class="pln">  </span><span class="com">// -1</span><span class="pln">
print</span><span class="pun">(</span><span class="str">'${a * b}'</span><span class="pun">);</span><span class="pln">  </span><span class="com">// 6</span><span class="pln">
print</span><span class="pun">(</span><span class="str">'${a / b}'</span><span class="pun">);</span><span class="pln">  </span><span class="com">// 0.6666666666666666</span><span class="pln">
print</span><span class="pun">(</span><span class="str">'${a ~/ b}'</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 0 (商)</span><span class="pln">
print</span><span class="pun">(</span><span class="str">'${a&nbsp;% b}'</span><span class="pun">);</span><span class="pln">  </span><span class="com">// 2 (余数)</span></pre>
<p>Dart 还支持前后缀自增减运算符。
</p>
<table class="operatorTable">
<tbody><tr>
<th> 运算符
</th>
<th> 定义
</th></tr>
<tr>
<td class="operator"> <code>++<i>变量</i></code>
</td>
<td> <code><i>变量</i> = <i>变量</i> + 1</code> （表达式值为 <code><i>变量</i> + 1</code>）
</td></tr>
<tr>
<td class="operator"> <code><i>变量</i>++</code>
</td>
<td> <code><i>变量</i> = <i>变量</i> + 1</code> （表达式值为 <code><i>变量</i></code>）
</td></tr>
<tr>
<td class="operator"> <code>--<i>变量</i></code>
</td>
<td> <code><i>变量</i> = <i>变量</i> – 1</code> （表达式值为 <code><i>变量</i> – 1</code>）
</td></tr>
<tr>
<td class="operator"> <code><i>变量</i>--</code>
</td>
<td> <code><i>变量</i> = <i>变量</i> – 1</code> （表达式值为 <code><i>变量</i></code>）
</td></tr></tbody></table>
<p>例：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">int</span><span class="pln"> a </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span><span class="pun">;</span><span class="pln">

print</span><span class="pun">(</span><span class="str">'${ ++a }'</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 3 （先自增后返回）</span><span class="pln">
print</span><span class="pun">(</span><span class="str">'${ a++ }'</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 3 （先返回后自增）</span><span class="pln">
print</span><span class="pun">(</span><span class="str">'${ a-- }'</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 4 （先返回后自减）</span><span class="pln">
print</span><span class="pun">(</span><span class="str">'${ --a }'</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 2 （先自减后返回）</span></pre>
<p><span id="op-equality"></span>
</p>
<h3> <span class="mw-headline" id=".E7.9B.B8.E7.AD.89.E6.80.A7.E4.B8.8E.E5.85.B3.E7.B3.BB.E8.BF.90.E7.AE.97.E7.AC.A6"> 相等性与关系运算符 </span></h3>
<table class="operatorTable">
<tbody><tr>
<th> 运算符
</th>
<th> 定义
</th></tr>
<tr>
<td class="operator"> <code>==</code>
</td>
<td> 相等 <i>（参见下文讨论）</i>
</td>
<td>
</td></tr>
<tr>
<td class="operator"> <code>!=</code>
</td>
<td> 不等
</td></tr>
<tr>
<td class="operator"> <code>===</code>
</td>
<td> 实例相同
</td></tr>
<tr>
<td class="operator"> <code>!==</code>
</td>
<td> 实例不同
</td></tr>
<tr>
<td class="operator"> <code>&gt;</code>
</td>
<td> 大于
</td></tr>
<tr>
<td class="operator"> <code>&lt;</code>
</td>
<td> 小于
</td></tr>
<tr>
<td class="operator"> <code>&gt;=</code>
</td>
<td> 大于或等于
</td></tr>
<tr>
<td class="operator"> <code>&lt;=</code>
</td>
<td> 小于或等于
</td></tr>
<tr>
<td class="operator"> <code>is</code>
</td>
<td> 如果对象为指定类型则为 <code>true</code> <i>（参见下文讨论）</i>
</td></tr>
<tr>
<td class="operator"> <code>is!</code>
</td>
<td> 如果对象为指定类型则为 <code>false</code>
</td></tr></tbody></table>
<p>要测试 <code>x</code> 与 <code>y</code> 两个对象是否代表相同的事物，请使用 <b><code>==</code></b> 运算符。
您通常不必使用 <b><code>===</code></b> 运算符，该运算符用于测试两个对象是否是完全一样的对象。
<b><code>==</code></b> 运算符的工作原理如下：
</p>
<ol><li> 如果 <code>x===y</code>，返回 <code>true</code>。
</li><li> 否则，如果 <code>x</code> 或 <code>y</code> 为 <code>null</code>，则返回 <code>false</code>。
</li><li> 否则，返回表达式 <code>x.equals(y)</code> 的结果。
</li></ol>
<p><b><code>is</code></b> 与 <b><code>is!</code></b> 运算符可方便检查类型。
如果 <code>对象</code> 实现了 <code>T</code> 所指定的接口，
则 <code>对象 <b>is</b> T</code> 的结果为 <code>true</code>。
例如，<code>对象 <b>is</b> Object</code> 总为 <code>true</code>。
</p><p>下面的例子用到了各个相等性与关系运算符：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">int</span><span class="pln"> a </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> b </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> c </span><span class="pun">=</span><span class="pln"> a</span><span class="pun">;</span><span class="pln">

print</span><span class="pun">(</span><span class="pln">a </span><span class="pun">==</span><span class="pln"> </span><span class="lit">2</span><span class="pun">);</span><span class="pln">       </span><span class="com">// true；2 与 2 相等</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">a&nbsp;</span><span class="pun">!=</span><span class="pln"> b</span><span class="pun">);</span><span class="pln">       </span><span class="com">// true；2 与 3 不等</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">a </span><span class="pun">===</span><span class="pln"> c</span><span class="pun">);</span><span class="pln">      </span><span class="com">// true；a 与 c 是完全相同的对象</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">a&nbsp;</span><span class="pun">!==</span><span class="pln"> b</span><span class="pun">);</span><span class="pln">      </span><span class="com">// true；2 与 3 不是相同的对象</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">b </span><span class="pun">&gt;</span><span class="pln"> a</span><span class="pun">);</span><span class="pln">        </span><span class="com">// true；3 大于 2</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">a </span><span class="pun">&lt;</span><span class="pln"> b</span><span class="pun">);</span><span class="pln">        </span><span class="com">// true；2 小于 3</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">b </span><span class="pun">&gt;=</span><span class="pln"> b</span><span class="pun">);</span><span class="pln">       </span><span class="com">// true；3 大于或等于 3</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">a </span><span class="pun">&lt;=</span><span class="pln"> b</span><span class="pun">);</span><span class="pln">       </span><span class="com">// true；2 小于或等于 3</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">a is </span><span class="kwd">num</span><span class="pun">);</span><span class="pln">     </span><span class="com">// true；2 是数字类型</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">a is</span><span class="pun">!</span><span class="pln"> </span><span class="typ">String</span><span class="pun">);</span><span class="pln"> </span><span class="com">// true；2 是 int 而非字符串类型</span></pre>
<p><span id="op-equality"></span>
</p>
<h3> <span class="mw-headline" id=".E8.B5.8B.E5.80.BC.E8.BF.90.E7.AE.97.E7.AC.A6"> 赋值运算符 </span></h3>
<p>您可以使用 <b><code>=</code></b> 运算符进行赋值。
也可以使用组合赋值运算符，
它们是运算符与赋值操作的结合。
</p>
<table>
<tbody><tr>
<th>
</th>
<th> 组合赋值符
</th>
<th> 等效表达式
</th></tr>
<tr>
<th align="left"> 对于运算符 <code><i>op</i></code>：
</th>
<td> <code>a <i>op</i>= b</code>
</td>
<td> <code>a = a <i>op</i> b</code>
</td></tr>
<tr>
<th align="left"> 例：
</th>
<td> <code>a += b</code>
</td>
<td> <code>a = a + b</code>
</td></tr></tbody></table>
<p>下面是赋值运算符总表：
</p>
<p style="column-count:4; -webkit-column-count:4"><code>
= <br>
+= <br>
–= <br>
*= <br>
/= <br>
~/= <br>
%= <br>
&lt;&lt;= <br>
&gt;&gt;= <br>
&amp;= <br>
^= <br>
|=
</code></p>
<p>下面的例子同时用到了赋值符和组合赋值运算符：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">int</span><span class="pln"> a </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span><span class="pun">;</span><span class="pln">           </span><span class="com">// 使用 = 赋值</span><span class="pln">

a </span><span class="pun">*=</span><span class="pln"> </span><span class="lit">3</span><span class="pun">;</span><span class="pln">              </span><span class="com">// 相乘并赋值：a = a * 3</span><span class="pln">
print</span><span class="pun">(</span><span class="str">'a *= 3: $a'</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 输出 a *= 3: 6</span></pre>
<p><span id="op-logical"></span>
</p>
<h3> <span class="mw-headline" id=".E9.80.BB.E8.BE.91.E8.BF.90.E7.AE.97.E7.AC.A6"> 逻辑运算符 </span></h3>
<p>您可以使用逻辑运算符对布尔表达式进行取反或组合。
</p>
<table class="operatorTable">
  <tbody><tr> <th> 运算符 </th> <th> 定义 </th> </tr>
  <tr>
    <td class="operator"> <code>!<em>表达式</em></code> </td>
    <td> 反转以下表达式
      （false 变为 true，反之亦然） </td>
  </tr><tr>
    <td class="operator"> <code>||</code> </td>
    <td> 逻辑 OR </td>
  </tr><tr>
    <td class="operator"> <code>&amp;&amp;</code> </td>
    <td> 逻辑 AND </td>
  </tr>
</tbody></table>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">done </span><span class="pun">&amp;&amp;</span><span class="pln"> </span><span class="pun">(</span><span class="pln">col </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="pun">||</span><span class="pln"> col </span><span class="pun">==</span><span class="pln"> </span><span class="lit">3</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="com">// ...执行一些操作</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><span id="op-bit"></span>
</p>
<h3> <span class="mw-headline" id=".E4.BD.8D.E6.93.8D.E4.BD.9C.E4.B8.8E.E7.A7.BB.E4.BD.8D.E8.BF.90.E7.AE.97.E7.AC.A6"> 位操作与移位运算符 </span></h3>
<p>在 Dart 中，您可以操作对象各位。
这些运算符通常应与整数搭配使用。
</p>
<table class="operatorTable">
  <tbody><tr> <th> 运算符 </th> <th> 定义 </th> </tr>
  <tr>
    <td class="operator"> <code>&amp;</code> </td>
    <td> AND </td>
  </tr><tr>
    <td class="operator"> <code>|</code> </td>
    <td> OR </td>
  </tr><tr>
    <td class="operator"> <code>^</code> </td>
    <td> XOR </td>
  </tr><tr>
    <td class="operator"> <code>~<em>表达式</em></code> </td>
    <td> 一元位取补（<code>0</code> 变 <code>1</code>；<code>1</code> 变 <code>0</code>） </td>
  </tr><tr>
    <td class="operator"> <code>&lt;&lt;</code> </td>  <td> 左移 </td>
  </tr><tr>
    <td class="operator"> <code>&gt;&gt;</code> </td>  <td> 右移 </td>
  </tr><tr>
</tr></tbody></table>
<p>下例使用了位操作与移位运算符。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">int</span><span class="pln"> value </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0x22</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">int</span><span class="pln"> bitmask </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0x0F</span><span class="pun">;</span><span class="pln">

print</span><span class="pun">(</span><span class="pln">value</span><span class="pun">);</span><span class="pln">                                </span><span class="com">// 34 (0x22)</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">value</span><span class="pun">.</span><span class="pln">toRadixString</span><span class="pun">(</span><span class="lit">16</span><span class="pun">));</span><span class="pln">              </span><span class="com">// 22</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">value</span><span class="pun">.</span><span class="pln">toRadixString</span><span class="pun">(</span><span class="lit">2</span><span class="pun">));</span><span class="pln">               </span><span class="com">// 100010</span><span class="pln">
print</span><span class="pun">((</span><span class="pln">value </span><span class="pun">&amp;</span><span class="pln"> bitmask</span><span class="pun">).</span><span class="pln">toRadixString</span><span class="pun">(</span><span class="lit">16</span><span class="pun">));</span><span class="pln">  </span><span class="com">// 2  (AND)</span><span class="pln">
print</span><span class="pun">((</span><span class="pln">value </span><span class="pun">&amp;</span><span class="pln"> </span><span class="pun">~</span><span class="pln">bitmask</span><span class="pun">).</span><span class="pln">toRadixString</span><span class="pun">(</span><span class="lit">16</span><span class="pun">));</span><span class="pln"> </span><span class="com">// 20 (AND NOT)</span><span class="pln">
print</span><span class="pun">((</span><span class="pln">value </span><span class="pun">|</span><span class="pln"> bitmask</span><span class="pun">).</span><span class="pln">toRadixString</span><span class="pun">(</span><span class="lit">16</span><span class="pun">));</span><span class="pln">  </span><span class="com">// 2f (OR)</span><span class="pln">
print</span><span class="pun">((</span><span class="pln">value </span><span class="pun">^</span><span class="pln"> bitmask</span><span class="pun">).</span><span class="pln">toRadixString</span><span class="pun">(</span><span class="lit">16</span><span class="pun">));</span><span class="pln">  </span><span class="com">// 2d (XOR)</span><span class="pln">
print</span><span class="pun">((</span><span class="pln">value </span><span class="pun">&lt;&lt;</span><span class="pln"> </span><span class="lit">4</span><span class="pun">).</span><span class="pln">toRadixString</span><span class="pun">(</span><span class="lit">16</span><span class="pun">));</span><span class="pln">       </span><span class="com">// 220</span><span class="pln">
print</span><span class="pun">((</span><span class="pln">value </span><span class="pun">&gt;&gt;</span><span class="pln"> </span><span class="lit">4</span><span class="pun">).</span><span class="pln">toRadixString</span><span class="pun">(</span><span class="lit">16</span><span class="pun">));</span><span class="pln">       </span><span class="com">// 2</span></pre>
<p><span id="op-other"></span>
</p>
<h3> <span class="mw-headline" id=".E5.85.B6.E4.BB.96.E8.BF.90.E7.AE.97.E7.AC.A6"> 其他运算符 </span></h3>
<table class="operatorTable">
  <tbody><tr> <th style="text-align:center"> 运算符 </th> <th> 名称 </th> <th> 定义 </th> </tr>
  <tr>
    <td class="operator"> <code>()</code> </td>
    <td> 函数应用 </td>
    <td> 代表函数调用 </td>
  </tr><tr>
    <td class="operator"> <code>[]</code> </td>
    <td> 列表访问 </td>
    <td> 代表列表特定索引位置的值 </td>
  </tr><tr>
    <td class="operator"> <code><em>表达式1</em>&nbsp;? <em>表达式2</em>&nbsp;: <em>表达式3</em></code> </td>
    <td> 条件 </td>
    <td> 如果 <code><em>表达式1</em></code> 为 <code>true</code>，则执行 <code><em>expr2</em></code>；
<p>否则，执行 <code><em>表达式3</em></code>
</p>
（技术上讲属于特别语法，不是运算符）</td>
  </tr><tr>
    <td class="operator"> <code>.</code> </td>
    <td> 成员访问 </td>
    <td> 代表表达式的一个属性；
例：<code>foo.bar</code> 从表达式 <code>foo</code> 中选取属性 <code>bar</code></td>
  </tr>
</tbody></table>
<p><span id="op-methods"></span><span id=".E8.BF.90.E7.AE.97.E7.AC.A6.E4.BD.9C.E4.B8.BA.E6.96.B9.E6.B3.95.E8.B0.83.E7.94.A8"></span>
</p>
<h3> <span class="mw-headline" id=".E8.BF.90.E7.AE.97.E7.AC.A6.E7.9A.84.E6.96.B9.E6.B3.95.E6.9C.AC.E8.B4.A8"> 运算符的方法本质 </span></h3>
<p>运算符只是名字比较特别的实例方法。
例如，表达式 <code>1 + 2</code>
调用了 <code>1</code> 的 <code>+</code> 方法，参数为 <code>2</code>—即
<code>1.+(2)</code>。
这种模型有重要意义：
</p>
<ul>
<li>Dart 允许您重载很多运算符。
例如，如果您定义了 Vector 类，
可以再定义一个 <code>+</code> 方法，用来求两个向量之和。</li>
<li>对于二元运算符，
左侧的运算元决定了
应选用运算符的版本。
例如，如果您定义了 Vector 类与 Point 类，
<code>aVector + aPoint</code> 中会使用 Vector 版本的 <code>+</code>。
</li>
</ul>
<p>以下运算符可以重载：
</p>
<p style="column-count:4; -webkit-column-count:4"><code>
&lt; <br>
&gt; <br>
&lt;= <br>
&gt;= <br>
– <br>
+ <br>
/ <br>
~/ <br>
* <br>
% <br>
| <br>
^ <br>
&amp; <br>
&lt;&lt; <br>
&gt;&gt; <br>
[]</code>  <br>
<code>[]=</code> <em>(列表赋值)</em> <br>
<code>~</code> <br>

<code>equals()</code> <em>(</em><code>==</code><em>)</em>  <sup><a href="#equals">*</a></sup>

</p>
<div class="note">
<p><span id="equals"></span><sup>*</sup> 目前 <strong><code>==</code></strong> 运算符可以重载，但不会一直这样。
不久以后，自定义 <strong><code>==</code></strong> 动作的途径
将是重载 <strong><code>equals()</code></strong> 方法。
</p>
</div>
<p>关于重载运算符的例子，请参见《类》一节的<a href="#classes-operators">运算符</a>段落。
</p><p><span id="op-summary"></span>
</p>
<h3> <span class="mw-headline" id=".E8.BF.90.E7.AE.97.E7.AC.A6.E5.B0.8F.E7.BB.93"> 运算符小结 </span></h3>
<p>Dart 运算符的外观与行为应该不令人感到陌生。
从技术层面来看，运算符是特别命名的方法，
在首个操作数处调用。
因此，操作数的顺序可能会造成差异：
<code>a+b</code> 的结果可能与 <code>b+a</code> 的不尽相同。
您可以重载很多运算符。
</p><p><span id="control-flow"></span>
</p>
<h2> <span class="mw-headline" id=".E6.B5.81.E7.A8.8B.E6.8E.A7.E5.88.B6"> 流程控制 </span></h2>
<p>您可以使用下述语句控制 Dart 代码的执行流程：
</p>
<ul><li> <a href="#if-else">if 与 else</a>
</li><li> <a href="#for-loops">for 循环</a>
</li><li> <a href="#while">while 与 do while</a>
</li><li> <a href="#break">break 与 continue</a>
</li><li> <a href="#switch">switch 与 case</a>
</li></ul>
<p><span id="if-else"></span>
</p>
<h4> <span class="mw-headline" id="if_.E4.B8.8E_else"> if 与 else </span></h4>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">isRaining</span><span class="pun">())</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  you</span><span class="pun">.</span><span class="pln">bringRainCoat</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">isSnowing</span><span class="pun">())</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  you</span><span class="pun">.</span><span class="pln">wearJacket</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  car</span><span class="pun">.</span><span class="pln">putTopDown</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>请记住，与 JavaScript 不同，Dart 将所有
非 <code>true</code> 的值当作 <code>false</code> 对待。
详情请参见<a href="#booleans">布尔值</a>。
</p><p><span id="for-loops"></span>
</p>
<h4> <span class="mw-headline" id="for_.E5.BE.AA.E7.8E.AF"> for 循环 </span></h4>
<p>您可以使用标准 <code>for</code> 循环进行遍历。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> i </span><span class="pun">&lt;</span><span class="pln"> candidates</span><span class="pun">.</span><span class="pln">length</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  candidates</span><span class="pun">[</span><span class="pln">i</span><span class="pun">].</span><span class="pln">interview</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>Dart 中 <code>for</code> 循环的退出可以正确捕获索引值，
没有 JavaScript 中讨厌的设计缺陷。
例如可以这样：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  var callbacks </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[];</span><span class="pln">
  </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="pln">var i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> i </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">2</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    callbacks</span><span class="pun">.</span><span class="pln">add</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> print</span><span class="pun">(</span><span class="pln">i</span><span class="pun">));</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
  callbacks</span><span class="pun">.</span><span class="pln">forEach</span><span class="pun">((</span><span class="pln">c</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> c</span><span class="pun">());</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>输出内容是 <code>0</code>、<code>1</code>，与预期的一样。
相反，在 JavaScript 中，该例会输出 <code>2</code>、<code>2</code>。
</p><p>如果您要遍历的对象是 <code>Collection</code> 类型，
可以使用 <code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Collection.html#forEach">forEach()</a></code>
方法。如果不需要知道当前遍历的位置，
使用 <code>forEach()</code> 是个不错的选择。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">candidates</span><span class="pun">.</span><span class="pln">forEach</span><span class="pun">((</span><span class="pln">candidate</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> candidate</span><span class="pun">.</span><span class="pln">interview</span><span class="pun">());</span></pre>
<p>集合还支持 <code>for-in</code> 形式的遍历：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var collection </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">];</span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="pln">var x in collection</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">x</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="com">// 输出内容:</span><span class="pln">
</span><span class="com">// 0</span><span class="pln">
</span><span class="com">// 1</span><span class="pln">
</span><span class="com">// 2</span></pre>
<p><span id="while"></span>
</p>
<h4> <span class="mw-headline" id="while_.E4.B8.8E_do_while"> while 与 do while </span></h4>
<p><code>while</code> 循环语句可在循环前判断条件是否成立。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">while</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">auctionItem</span><span class="pun">.</span><span class="pln">currentWinner</span><span class="pun">(</span><span class="pln">bidder</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&amp;&amp;</span><span class="pln">
       auctionItem</span><span class="pun">.</span><span class="pln">currentBid </span><span class="pun">&lt;</span><span class="pln"> bidder</span><span class="pun">.</span><span class="pln">maximumBid</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  auctionItem</span><span class="pun">.</span><span class="pln">placeBid</span><span class="pun">(</span><span class="pln">bidder</span><span class="pun">,</span><span class="pln"> auction</span><span class="pun">.</span><span class="pln">currentBid </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><code>do while</code> 循环可在循环<em>之后</em>判断条件是否成立。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">do</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  printLine</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">while</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">atEndOfPage</span><span class="pun">());</span></pre>
<p><span id="break"></span>
</p>
<h4> <span class="mw-headline" id="break_.E4.B8.8E_continue"> break 与 continue </span></h4>
<p>使用 <code>break</code> 停止循环。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">while</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">true</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">shutDownRequested</span><span class="pun">())</span><span class="pln"> </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
  processIncomingRequests</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>使用 <code>continue</code> 跳到下一次循环遍历。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> i </span><span class="pun">&lt;</span><span class="pln"> candidates</span><span class="pun">.</span><span class="pln">length</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  var candidate </span><span class="pun">=</span><span class="pln"> candidates</span><span class="pun">[</span><span class="pln">i</span><span class="pun">];</span><span class="pln">
  </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">candidate</span><span class="pun">.</span><span class="pln">yearsExperience </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">5</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">continue</span><span class="pun">;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
  candidate</span><span class="pun">.</span><span class="pln">interview</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>如果您在使用 <a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Collection.html">Collection</a>，该例还可以这样写：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">candidates</span><span class="pun">.</span><span class="pln">filter</span><span class="pun">((</span><span class="pln">c</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> c</span><span class="pun">.</span><span class="pln">yearsExperience </span><span class="pun">&gt;=</span><span class="pln"> </span><span class="lit">5</span><span class="pun">)</span><span class="pln">
          </span><span class="pun">.</span><span class="pln">forEach</span><span class="pun">((</span><span class="pln">c</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> c</span><span class="pun">.</span><span class="pln">interview</span><span class="pun">());</span></pre>
<p><span id="switch"></span>
</p>
<h4> <span class="mw-headline" id="switch_.E4.B8.8E_case"> switch 与 case </span></h4>
<p>Dart 中的 switch 语句使用 <code>==</code> 比较对象。记得在每条非空 <code>case</code>
分句后加上 <code>break</code> 语句，以避免跳到下一句（属于错误，参见下文）。
<code>default</code> 分句可用于捕获无匹配的条件。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var command </span><span class="pun">=</span><span class="pln"> </span><span class="str">'OPEN'</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">switch</span><span class="pln"> </span><span class="pun">(</span><span class="pln">command</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">case</span><span class="pln"> </span><span class="str">'CLOSED'</span><span class="pun">:</span><span class="pln">
    executeClose</span><span class="pun">();</span><span class="pln">
    </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">case</span><span class="pln"> </span><span class="str">'PENDING'</span><span class="pun">:</span><span class="pln">
    executePending</span><span class="pun">();</span><span class="pln">
    </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">case</span><span class="pln"> </span><span class="str">'APPROVED'</span><span class="pun">:</span><span class="pln">
    executeApproved</span><span class="pun">();</span><span class="pln">
    </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">case</span><span class="pln"> </span><span class="str">'DENIED'</span><span class="pun">:</span><span class="pln">
    executeDenied</span><span class="pun">();</span><span class="pln">
    </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">case</span><span class="pln"> </span><span class="str">'OPEN'</span><span class="pun">:</span><span class="pln">
    executeOpen</span><span class="pun">();</span><span class="pln">
    </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">default</span><span class="pun">:</span><span class="pln">
    executeUnknown</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>下例的 <code>case</code> 分句中省略了 <code>break</code> 语句，
会引发报错：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var command </span><span class="pun">=</span><span class="pln"> </span><span class="str">'OPEN'</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">switch</span><span class="pln"> </span><span class="pun">(</span><span class="pln">command</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

  </span><span class="kwd">case</span><span class="pln"> </span><span class="str">'OPEN'</span><span class="pun">:</span><span class="pln">
    executeOpen</span><span class="pun">();</span><span class="pln">
    </span><span class="com">// 错误：缺少 break 会触发异常!!</span><span class="pln">

  </span><span class="kwd">case</span><span class="pln"> </span><span class="str">'CLOSED'</span><span class="pun">:</span><span class="pln">
    executeClose</span><span class="pun">();</span><span class="pln">
    </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>不过 Dart 的确支持空的 <code>case</code> 分句，
允许跳到下一分句。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var command </span><span class="pun">=</span><span class="pln"> </span><span class="str">'CLOSED'</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">switch</span><span class="pln"> </span><span class="pun">(</span><span class="pln">command</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">case</span><span class="pln"> </span><span class="str">'CLOSED'</span><span class="pun">:</span><span class="pln">     </span><span class="com">// 空分句会跳到下一分句</span><span class="pln">
  </span><span class="kwd">case</span><span class="pln"> </span><span class="str">'NOW_CLOSED'</span><span class="pun">:</span><span class="pln">
    </span><span class="com">// CLOSED 与 NOW_CLOSED 均执行这段代码</span><span class="pln">
    executeClose</span><span class="pun">();</span><span class="pln">
    </span><span class="kwd">break</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><span id="exceptions"></span>
</p>
<h2> <span class="mw-headline" id=".E5.BC.82.E5.B8.B8.E5.A4.84.E7.90.86"> 异常处理 </span></h2>
<p>Dart 代码可以抛出与捕捉异常。
异常是预期以外情况发生的错误信号。
如果没有捕捉，
异常将不断返回至程序顶层。
</p><p>与 Java 不同的是，Dart 的所有异常都是非强制异常。
方法不会声明可能抛出的异常，
您也不必捕捉所有异常。
</p><p>Dart 提供了 <code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Exception.html">Exception</a></code> 接口以及很多预定义的异常类型。
当然,您可以通过扩展 <code>Exception</code> 接口定义自己的异常类型。
常见异常的例子包括：
</p>
<ul><li> <a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/IndexOutOfRangeException.html">IndexOutOfRangeException</a> 索引越界
</li><li> <a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/NoSuchMethodException.html">NoSuchMethodException</a> 无此方法
</li><li> <a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/NullPointerException.html">NullPointerException</a> null 指针
</li><li> <a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/IllegalArgumentException.html">IllegalArgumentException</a> 参数非法
</li></ul>
<p>不过，Dart 程序可以将任意对象作为异常抛出。
</p>
<h4> <span class="mw-headline" id=".E6.8A.9B.E5.87.BA"> 抛出 </span></h4>
<p>您可以这样抛出——或者说 <em>引发</em>——异常。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">throw</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">IllegalArgumentException</span><span class="pun">(</span><span class="str">'数值必须大于零'</span><span class="pun">);</span></pre>
<p>您也可以抛出任意对象。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">throw</span><span class="pln"> </span><span class="str">"骆马不够用了!"</span><span class="pun">;</span></pre>
<h4> <span class="mw-headline" id=".E6.8D.95.E6.8D.89"> 捕捉 </span></h4>
<p>捕捉——或者说捕获——异常，可避免该异常向上级扩散。
捕捉为处理异常提供了可能。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">try</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  breedMoreLlamas</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">final</span><span class="pln"> </span><span class="typ">OutOfLlamasException</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  buyMoreLlamas</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>若要处理抛出多种类型异常的代码，您可以指定多条捕捉分句。
第一条捕捉分句匹配抛出对象的类型，
负责处理异常。
如果捕捉分句未指定类型，该分句将能处理任意类型的抛出对象。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">try</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  breedMoreLlamas</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">final</span><span class="pln"> </span><span class="typ">OutOfLlamasException</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">  </span><span class="com">// 特定异常</span><span class="pln">
  buyMoreLlamas</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">final</span><span class="pln"> </span><span class="typ">Exception</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">             </span><span class="com">// 任意异常</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"Unknown exception: $e"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">final</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">                       </span><span class="com">// 类型不确定，全部处理</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"Something really unknown: $e"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<h4> <span class="mw-headline" id="finally"> <code>finally</code> </span></h4>
<p>为确保不论是否有异常抛出，仍有一部分代码能够执行，
请使用 <code>finally</code> 分句。
</p><p>如果没有捕捉分句与异常相匹配，
将执行 <code>finally</code> 分句，而异常也将不断扩散。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">try</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  breedMoreLlamas</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">finally</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  cleanLlamaStalls</span><span class="pun">();</span><span class="pln">  </span><span class="com">// 总会执行，即使有异常抛出</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><code>finally</code> 分句也会在匹配到任意一条捕捉分句后执行。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">try</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  breedMoreLlamas</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">catch</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">final</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"Error: $e"</span><span class="pun">);</span><span class="pln">  </span><span class="com">// 先处理异常</span><span class="pln">
</span><span class="pun">}</span><span class="pln"> </span><span class="kwd">finally</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  cleanLlamaStalls</span><span class="pun">();</span><span class="pln">  </span><span class="com">// 然后执行 finally 分句</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><br>
<span id="classes"></span>
</p>
<h2> <span class="mw-headline" id=".E7.B1.BB"> 类 </span></h2>
<p>Dart 是一款面向对象的语言，支持类与单继承。
根类为
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Object.html">Object</a></code>。
</p>
<h3> <span class="mw-headline" id=".E5.AE.9E.E4.BE.8B.E5.8F.98.E9.87.8F"> 实例变量 </span></h3>
<p>您可以这样通过实例变量
（或称成员变量）
声明一个类：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Point</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">num</span><span class="pln"> x</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>所有未初始化的实例变量都有默认值 <code>null</code>。
</p><p>不论实例变量是否为 <code>final</code> 变量，
均隐式包含了 <code>getter</code> 方法。
非 <code>final</code> 实例变量
隐式包含了 <code>setter</code> 方法。
（<a href="#classes-getters-and-setters"><code>getter</code> 与 <code>setter</code></a> 将在下文深入讨论。）
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  var point </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Point</span><span class="pun">();</span><span class="pln">

  </span><span class="com">// 使用 x 的 setter 方法</span><span class="pln">
  point</span><span class="pun">.</span><span class="pln">x </span><span class="pun">=</span><span class="pln"> </span><span class="lit">4</span><span class="pun">;</span><span class="pln">

  </span><span class="com">// 使用 x 的 getter 方法</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">point</span><span class="pun">.</span><span class="pln">x</span><span class="pun">);</span><span class="pln">  </span><span class="com">// 4</span><span class="pln">

  </span><span class="com">// 默认值为 null</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">point</span><span class="pun">.</span><span class="pln">y</span><span class="pun">);</span><span class="pln">  </span><span class="com">// null</span><span class="pln">
</span><span class="pun">}</span></pre>
<h4> <span class="mw-headline" id=".E5.AE.9E.E4.BE.8B.E5.8F.98.E9.87.8F.E7.9A.84.E5.88.9D.E5.A7.8B.E5.8C.96"> 实例变量的初始化 </span></h4>
<p>如果您在声明
（而非通过构造函数或方法）
实例变量时对其进行初始化，
初始值必须为编译时常量。
</p>
<div class="note">
<p><strong>注：</strong>此限制目前尚在讨论当中。
</p>
</div>
<p>编译时常量的例子如数字常量：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Point</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">num</span><span class="pln"> x </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln">
      y </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>要给实例变量赋非常量值，
请使用构造函数体（将在下一段落讲解）。
</p>
<h3> <span class="mw-headline" id=".E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0"> 构造函数 </span></h3>
<p>您可以通过创建与类同名的方法来声明构造函数。
最常见的构造函数形式是
生成构造函数，
可创建该类的新实例。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Point</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">num</span><span class="pln"> x</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">

  </span><span class="typ">Point</span><span class="pun">(</span><span class="kwd">num</span><span class="pln"> x</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">num</span><span class="pln"> y</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="com">// 还有更好的方法实现，敬请期待</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">x </span><span class="pun">=</span><span class="pln"> x</span><span class="pun">;</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">y </span><span class="pun">=</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>关键词 <code>this</code> 可引用当前实例。
</p>
<div class="note">
<p><strong>注：</strong>仅当存在名字冲突时需要使用
<code>this</code>。其余情况下，Dart 的编写风格要求省略 <code>this</code>。
</p>
</div>
<p>将构造函数参数赋值给成员变量的语句特别常用，
因此 Dart 提供了简化代码的糖衣语法。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Point</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">num</span><span class="pln"> x</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">

  </span><span class="com">// this.x = x 与 this.y = y 的糖衣语法</span><span class="pln">
  </span><span class="typ">Point</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">y</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<h4> <span class="mw-headline" id=".E9.BB.98.E8.AE.A4.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0"> 默认构造函数 </span></h4>
<p>如果您不声明构造函数，
将会调用默认构造函数。
默认构造函数没有参数，
调用的是超类的无参构造函数。
</p>
<h4> <span class="mw-headline" id=".E5.88.9D.E5.A7.8B.E5.8C.96.E5.88.97.E8.A1.A8"> 初始化列表 </span></h4>
<p><code>final</code> 变量必须在对象赋值给 <code>this</code> 之前初始化。
您可以使用先于构造函数体执行的初始化列表
初始化任意 <code>final</code> 变量。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'dart:html'</span><span class="pun">);</span><span class="pln">

</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">Button</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">final</span><span class="pln"> </span><span class="typ">Collection</span><span class="pun">&lt;</span><span class="typ">ButtonHandler</span><span class="pun">&gt;</span><span class="pln"> handlers</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">final</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> domId</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">final</span><span class="pln"> </span><span class="typ">Element</span><span class="pln"> elem</span><span class="pun">;</span><span class="pln">
  
                </span><span class="com">//&nbsp;: 以后便是初始化列表</span><span class="pln">
  </span><span class="typ">Button</span><span class="pun">(</span><span class="pln">domId</span><span class="pun">)</span><span class="pln">&nbsp;</span><span class="pun">:</span><span class="pln"> domId </span><span class="pun">=</span><span class="pln"> domId</span><span class="pun">,</span><span class="pln">
                  handlers </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[],</span><span class="pln">
                  elem </span><span class="pun">=</span><span class="pln"> document</span><span class="pun">.</span><span class="pln">query</span><span class="pun">(</span><span class="pln">domId</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    bindHandlers</span><span class="pun">();</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  bindHandlers</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
   </span><span class="com">// ...</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>初始化语句的右侧无权访问
<code>this</code>。
</p>
<h4> <span class="mw-headline" id=".E5.91.BD.E5.90.8D.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0"> 命名构造函数 </span></h4>
<p>您可以使用命名构造函数实现同一个类的多个构造函数
或让代码更为清晰。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Point</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">num</span><span class="pln"> x</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">

  </span><span class="com">// 命名构造函数</span><span class="pln">
  </span><span class="typ">Point</span><span class="pun">.</span><span class="pln">fromJson</span><span class="pun">(</span><span class="typ">Map</span><span class="pln"> json</span><span class="pun">)</span><span class="pln">&nbsp;</span><span class="pun">:</span><span class="pln"> x </span><span class="pun">=</span><span class="pln"> json</span><span class="pun">[</span><span class="str">'x'</span><span class="pun">],</span><span class="pln"> y </span><span class="pun">=</span><span class="pln"> json</span><span class="pun">[</span><span class="str">'y'</span><span class="pun">];</span><span class="pln">

  </span><span class="typ">Point</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">y</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>通过 <code>new</code> 创建命名构造函数的新实例：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var jsonData </span><span class="pun">=</span><span class="pln"> JSON</span><span class="pun">.</span><span class="pln">parse</span><span class="pun">(</span><span class="str">'{"x":1, "y":2}'</span><span class="pun">);</span><span class="pln">
var point </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Point</span><span class="pun">.</span><span class="pln">fromJson</span><span class="pun">(</span><span class="pln">jsonData</span><span class="pun">);</span></pre>
<h4> <span class="mw-headline" id=".E5.B8.B8.E9.87.8F.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0"> 常量构造函数 </span></h4>
<p>Dart 的对象创建非常确定，
因此避免了其他语言中的棘手问题。
为实现这种确定性，Dart
中只允许将固定的编译时表达式
作为实例变量声明的初始值。
</p><p>固定的编译时常量对象也称为 <code>const</code> 对象。
要创建 <code>const</code> 对象，需要定义 <code>const</code>
构造函数，并确保所有实例字段均有 <code>final</code> 关键字。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Point</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">final</span><span class="pln"> </span><span class="kwd">num</span><span class="pln"> x</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">const</span><span class="pln"> </span><span class="typ">Point</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">y</span><span class="pun">);</span><span class="pln">
  </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">final</span><span class="pln"> </span><span class="typ">Point</span><span class="pln"> origin </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">const</span><span class="pln"> </span><span class="typ">Point</span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>由于编译时常量是常量且固定，
构造两个一样的 <code>const</code> 对象
会生成完全一样的实例。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">void</span><span class="pln"> main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  var a </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">const</span><span class="pln"> </span><span class="typ">Point</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln">
  var b </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">const</span><span class="pln"> </span><span class="typ">Point</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln">

  print</span><span class="pun">(</span><span class="pln">a </span><span class="pun">===</span><span class="pln"> b</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 输出 true，两个实例完全一样！</span><span class="pln">
</span><span class="pun">}</span></pre>
<div class="note">
<p><strong>注：</strong>其他运行时常量的例子如
数字常量与字符串常量。
</p>
</div>
<h4> <span class="mw-headline" id="factory_.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0"> <code>factory</code> 构造函数 </span></h4>
<p>要实现不总是创建类的新实例的构造函数，
可使用 <code>factory</code> 关键字。
例如，<code>factory</code> 构造函数
可能会返回缓存中的实例，
或是可能返回子类的实例。
</p><p>下例演示了返回缓存中对象的
<code>factory</code> 构造函数。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Logger</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">final</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> name</span><span class="pun">;</span><span class="pln">
  bool mute </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">

  </span><span class="kwd">static</span><span class="pln"> </span><span class="typ">Map</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Logger</span><span class="pun">&gt;</span><span class="pln"> _cache</span><span class="pun">;</span><span class="pln">

  factory </span><span class="typ">Logger</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> name</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">_cache </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      _cache </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{};</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">_cache</span><span class="pun">.</span><span class="pln">containsKey</span><span class="pun">(</span><span class="pln">name</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="kwd">return</span><span class="pln"> _cache</span><span class="pun">[</span><span class="pln">name</span><span class="pun">];</span><span class="pln">
    </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      </span><span class="kwd">final</span><span class="pln"> logger </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Logger</span><span class="pun">.</span><span class="pln">_internal</span><span class="pun">(</span><span class="pln">name</span><span class="pun">);</span><span class="pln">
      _cache</span><span class="pun">[</span><span class="pln">name</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> logger</span><span class="pun">;</span><span class="pln">
      </span><span class="kwd">return</span><span class="pln"> logger</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  </span><span class="typ">Logger</span><span class="pun">.</span><span class="pln">_internal</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">name</span><span class="pun">);</span><span class="pln">

  log</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> msg</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">mute</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      print</span><span class="pun">(</span><span class="pln">msg</span><span class="pun">);</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>对其他构造函数，
如需调用 <code>factory</code> 构造函数，您可以使用 <code>new</code> 关键字：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var logger </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Logger</span><span class="pun">(</span><span class="str">'UI'</span><span class="pun">);</span><span class="pln">
logger</span><span class="pun">.</span><span class="pln">log</span><span class="pun">(</span><span class="str">'按钮被点击了'</span><span class="pun">);</span></pre>
<div class="note">
<p><strong>注：</strong>factory 构造函数无权访问 <code>this</code>。
</p>
</div>
<h3> <span class="mw-headline" id=".E6.96.B9.E6.B3.95"> 方法 </span></h3>
<p>方法是提供对象行为的函数。
</p>
<h4> <span class="mw-headline" id=".E5.AE.9E.E4.BE.8B.E6.96.B9.E6.B3.95"> 实例方法 </span></h4>
<p>对象的实例方法可以访问实例变量与 <code>this</code>，
下例中的 <code>distanceTo()</code> 方法便是实例方法的一个例子。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Point</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">num</span><span class="pln"> x</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Point</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">y</span><span class="pun">);</span><span class="pln">

  </span><span class="kwd">num</span><span class="pln"> distanceTo</span><span class="pun">(</span><span class="typ">Point</span><span class="pln"> other</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="typ">Math</span><span class="pun">.</span><span class="pln">sqrt</span><span class="pun">(((</span><span class="pln">x</span><span class="pun">-</span><span class="pln">other</span><span class="pun">.</span><span class="pln">x</span><span class="pun">)*(</span><span class="pln">x</span><span class="pun">-</span><span class="pln">other</span><span class="pun">.</span><span class="pln">x</span><span class="pun">))</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="pun">((</span><span class="pln">y</span><span class="pun">-</span><span class="pln">other</span><span class="pun">.</span><span class="pln">y</span><span class="pun">)*(</span><span class="pln">y</span><span class="pun">-</span><span class="pln">other</span><span class="pun">.</span><span class="pln">y</span><span class="pun">)));</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>您可以这样调用 <code>Point</code> 实例的
<code>distanceTo()</code> 方法：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var point </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Point</span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">);</span><span class="pln">
</span><span class="kwd">num</span><span class="pln"> distance </span><span class="pun">=</span><span class="pln"> point</span><span class="pun">.</span><span class="pln">distanceTo</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Point</span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="lit">4</span><span class="pun">));</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">distance</span><span class="pun">);</span><span class="pln">  </span><span class="com">// 2.82842...</span></pre>
<p><span id="classes-getters-and-setters"></span>
</p>
<h4> <span class="mw-headline" id="getter_.E4.B8.8E_setter"> <code>getter</code> 与 <code>setter</code> </span></h4>
<p><code>getter</code> 与 <code>setter</code> 方法提供了对象内部状态的读写权限。
调用 <code>getter</code> 和 <code>setter</code> 时，
请省略后面的圆括号。
您可以使用 <code>get</code> 与 <code>set</code>
关键字定义 <code>getter</code> 与 <code>setter</code>。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Rectangle</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">num</span><span class="pln"> left</span><span class="pun">,</span><span class="pln"> top</span><span class="pun">,</span><span class="pln"> width</span><span class="pun">,</span><span class="pln"> height</span><span class="pun">;</span><span class="pln">

  </span><span class="typ">Rectangle</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">left</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">top</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">width</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">height</span><span class="pun">);</span><span class="pln">

  </span><span class="kwd">num</span><span class="pln"> get right</span><span class="pun">()</span><span class="pln">           </span><span class="pun">=&gt;</span><span class="pln"> left </span><span class="pun">+</span><span class="pln"> width</span><span class="pun">;</span><span class="pln">
      set right</span><span class="pun">(</span><span class="kwd">num</span><span class="pln"> value</span><span class="pun">)</span><span class="pln">  </span><span class="pun">=&gt;</span><span class="pln"> left </span><span class="pun">=</span><span class="pln"> value </span><span class="pun">-</span><span class="pln"> width</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">num</span><span class="pln"> get bottom</span><span class="pun">()</span><span class="pln">          </span><span class="pun">=&gt;</span><span class="pln"> top </span><span class="pun">+</span><span class="pln"> height</span><span class="pun">;</span><span class="pln">
      set bottom</span><span class="pun">(</span><span class="kwd">num</span><span class="pln"> value</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> top </span><span class="pun">=</span><span class="pln"> value </span><span class="pun">-</span><span class="pln"> height</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><br>
对 <code>getter</code> 与 <code>setter</code> 的调用
与使用实例变量所生成的 <code>getter</code> 与 <code>setter</code>
无异。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var rect </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Rectangle</span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="lit">20</span><span class="pun">,</span><span class="pln"> </span><span class="lit">15</span><span class="pun">);</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">rect</span><span class="pun">.</span><span class="pln">left</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 3</span><span class="pln">
rect</span><span class="pun">.</span><span class="pln">right </span><span class="pun">=</span><span class="pln"> </span><span class="lit">12</span><span class="pun">;</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">rect</span><span class="pun">.</span><span class="pln">left</span><span class="pun">);</span><span class="pln"> </span><span class="com">// -8</span></pre>
<p>有了 <code>getter</code> 与 <code>setter</code>，
您可以将实例变量封装成方法，
而不必修改客户端代码。
</p><p><span id="classes-operators"></span>
</p>
<h4> <span class="mw-headline" id=".E8.BF.90.E7.AE.97.E7.AC.A6_2"> 运算符 </span></h4>
<p>由于运算符只是名称特别的实例方法，
您可以重载<a href="#op-methods">很多运算符</a>。
下例中的类重载了 <code>+</code> 与 <code>-</code> 运算符。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Vector</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">final</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> x</span><span class="pun">,</span><span class="pln">y</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">const</span><span class="pln"> </span><span class="typ">Vector</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">y</span><span class="pun">);</span><span class="pln">

  </span><span class="typ">Vector</span><span class="pln"> </span><span class="kwd">operator</span><span class="pln"> </span><span class="pun">+(</span><span class="typ">Vector</span><span class="pln"> v</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="com">// 重载 + (a + b)</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Vector</span><span class="pun">(</span><span class="pln">x </span><span class="pun">+</span><span class="pln"> v</span><span class="pun">.</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> y </span><span class="pun">+</span><span class="pln"> v</span><span class="pun">.</span><span class="pln">y</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
  
  </span><span class="typ">Vector</span><span class="pln"> </span><span class="kwd">operator</span><span class="pln"> </span><span class="pun">-(</span><span class="typ">Vector</span><span class="pln"> v</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="com">// 重载 - (a - b)</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Vector</span><span class="pun">(</span><span class="pln">x </span><span class="pun">-</span><span class="pln"> v</span><span class="pun">.</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> y </span><span class="pun">-</span><span class="pln"> v</span><span class="pun">.</span><span class="pln">y</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
  
  </span><span class="typ">Vector</span><span class="pln"> </span><span class="kwd">operator</span><span class="pln"> negate</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">    </span><span class="com">// 重载一元取反运算符 (-a)</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Vector</span><span class="pun">(-</span><span class="pln">x</span><span class="pun">,-</span><span class="pln">y</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
  
  </span><span class="typ">String</span><span class="pln"> toString</span><span class="pun">()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="str">'($x,$y)'</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">Vector</span><span class="pln"> v </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Vector</span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="lit">3</span><span class="pun">);</span><span class="pln">
  </span><span class="typ">Vector</span><span class="pln"> w </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Vector</span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="lit">2</span><span class="pun">);</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">v</span><span class="pun">);</span><span class="pln">   </span><span class="com">// (2,3)</span><span class="pln">
  print</span><span class="pun">(-</span><span class="pln">v</span><span class="pun">);</span><span class="pln">  </span><span class="com">// (-2,-3)</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">v</span><span class="pun">+</span><span class="pln">w</span><span class="pun">);</span><span class="pln"> </span><span class="com">// (4,5)</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">v</span><span class="pun">-</span><span class="pln">w</span><span class="pun">);</span><span class="pln"> </span><span class="com">// (0,1)</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><br>
</p>
<div class="note">
<p><strong>实作时请注意：</strong>
重载 <code>-</code> 运算符只会影响二进制的减法运算。
如需重载一元形式的 <code>-</code>，
您必须使用特别的标识符 <code><strong>negate</strong></code>。
</p>
</div>
<h3> <span class="mw-headline" id=".E6.8A.BD.E8.B1.A1.E7.B1.BB"> 抽象类 </span></h3>
<p>Dart 即将支持抽象类与抽象方法。
</p><p>至 2012 年 4 月 4 日，抽象类尚未实现。
请关注 bug <a rel="nofollow" class="external text" href="http://code.google.com/p/dart/issues/detail?id=1603">1603</a>
与 bug <a rel="nofollow" class="external text" href="http://code.google.com/p/dart/issues/detail?id=1605">1605</a>
以跟踪开发进展。
</p>
<h3> <span class="mw-headline" id=".E6.89.A9.E5.B1.95.E7.B1.BB"> 扩展类 </span></h3>
<p>使用 <code>extends</code> 关键字可创建子类，<code>super</code>
关键词可引用其超类。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Television</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  turnOn</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    _illuminateDisplay</span><span class="pun">();</span><span class="pln">
    _activeIrSensor</span><span class="pun">();</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">SmartTelevision</span><span class="pln"> </span><span class="kwd">extends</span><span class="pln"> </span><span class="typ">Television</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  turnOn</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">super</span><span class="pun">.</span><span class="pln">turnOn</span><span class="pun">();</span><span class="pln">
    _bootNetworkInterface</span><span class="pun">();</span><span class="pln">
    _initializeMemory</span><span class="pun">();</span><span class="pln">
    _upgradeApps</span><span class="pun">();</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>子类可重载实例的方法、<code>getter</code> 及 <code>setter</code>。
</p>
<h3> <span class="mw-headline" id=".E7.B1.BB.E7.BA.A7.E9.9D.99.E6.80.81.E6.88.90.E5.91.98"> 类级静态成员 </span></h3>
<p>使用 <code>static</code> 关键字可实现类级别的变量与方法。
</p>
<h4> <span class="mw-headline" id=".E9.9D.99.E6.80.81.E6.96.B9.E6.B3.95"> 静态方法 </span></h4>
<p>静态方法（类级方法）不操作实例，
因此无权访问 <code>this</code>。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Point</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">num</span><span class="pln"> x</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">Point</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">x</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">y</span><span class="pun">);</span><span class="pln">

  </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">num</span><span class="pln"> distanceBetween</span><span class="pun">(</span><span class="typ">Point</span><span class="pln"> a</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Point</span><span class="pln"> b</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="typ">Math</span><span class="pun">.</span><span class="pln">sqrt</span><span class="pun">(((</span><span class="pln">a</span><span class="pun">.</span><span class="pln">x</span><span class="pun">-</span><span class="pln">b</span><span class="pun">.</span><span class="pln">x</span><span class="pun">)*(</span><span class="pln">a</span><span class="pun">.</span><span class="pln">x</span><span class="pun">-</span><span class="pln">b</span><span class="pun">.</span><span class="pln">x</span><span class="pun">))</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="pun">((</span><span class="pln">a</span><span class="pun">.</span><span class="pln">y</span><span class="pun">-</span><span class="pln">b</span><span class="pun">.</span><span class="pln">y</span><span class="pun">)*(</span><span class="pln">a</span><span class="pun">.</span><span class="pln">y</span><span class="pun">-</span><span class="pln">b</span><span class="pun">.</span><span class="pln">y</span><span class="pun">)));</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  var a </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Point</span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">);</span><span class="pln">
  var b </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Point</span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">);</span><span class="pln">
  print</span><span class="pun">(</span><span class="typ">Point</span><span class="pun">.</span><span class="pln">distanceBetween</span><span class="pun">(</span><span class="pln">a</span><span class="pun">,</span><span class="pln"> b</span><span class="pun">));</span><span class="pln">  </span><span class="com">// 2.82842...</span><span class="pln">
</span><span class="pun">}</span></pre>
<div class="note">
<p><strong>最佳实践：</strong>对于常用或广泛使用的功能和函数，
请考虑使用顶级函数
</p>
替代静态方法。</div>
<h4> <span class="mw-headline" id=".E9.9D.99.E6.80.81.E5.8F.98.E9.87.8F"> 静态变量 </span></h4>
<p>静态变量（类级变量）对处理类级状态与常量非常有用。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Color</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">static</span><span class="pln"> </span><span class="kwd">final</span><span class="pln"> RED </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">const</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">(</span><span class="str">'红色'</span><span class="pun">);</span><span class="pln">
  </span><span class="kwd">final</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> name</span><span class="pun">;</span><span class="pln">
  </span><span class="kwd">const</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">name</span><span class="pun">);</span><span class="pln">
  </span><span class="typ">String</span><span class="pln"> toString</span><span class="pun">()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> name</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="typ">Color</span><span class="pun">.</span><span class="pln">RED</span><span class="pun">);</span><span class="pln"> </span><span class="com">// '红色'</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><span id="interfaces"></span>
</p>
<h2> <span class="mw-headline" id=".E6.8E.A5.E5.8F.A3"> 接口 </span></h2>
<p>接口是定义与对象交互方式的类型。
接口可以指定类型、
构造函数、
实例变量
（或者更精确地，<code>getter</code> 与 <code>setter</code>）
以及超接口。
不过接口不能指定方法与构造函数<em>当中的</em>代码。
</p><p>接口在指定 API
但不详细指定 API 如何实现时很方便。
</p><p><span id="interfaces-defining"></span>
</p>
<h3> <span class="mw-headline" id=".E5.AE.9A.E4.B9.89.E6.8E.A5.E5.8F.A3"> 定义接口 </span></h3>
<p>您可以使用 <code>interface</code> 关键词定义接口。
例如，下面的代码定义了
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Hashable.html">Hashable</a></code> 接口：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">interface </span><span class="typ">Hashable</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">int</span><span class="pln"> hashCode</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>注意定义的格式，接口没有方法体（<code>{...}</code>），
只有一个分号（<code>;</code>）。
</p><p><span id="interfaces-implementing"></span>
</p>
<h3> <span class="mw-headline" id=".E6.8E.A5.E5.8F.A3.E7.9A.84.E5.AE.9E.E7.8E.B0"> 接口的实现 </span></h3>
<p>类可以通过在 <code><strong>implements</strong></code>
分句中声明来实现一或多个接口，
并提供接口所需的 API。
例如：
</p><p><span class="prettyprint lang-dart linenums:0">
</span></p>
<pre>class Point <b>implements Hashable</b> {
  num x, y;
  ...
  // Hashable 所需的 API
  <b>int hashCode() {</b>
    int result = 17;
    result = 37 * result + x.hashCode();
    result = 37 * result + y.hashCode();
    return result;
  <b>}</b>
  ...
}
</pre>
<p>
</p><p>下例指定了
一个实现多个接口的类：
</p><p><span class="prettyprint lang-dart linenums:0">
</span></p>
<pre>class Point <b>implements Comparable, Hashable</b> {
  ...
}
</pre>
<p>
</p>
<div class="note">
<p><strong>注：</strong>
不久后您将能够将 Dart 类作为接口对待。
该功能在创建虚对象测试时会很有用。
</p>
</div>
<p><span id="interfaces-extending"></span>
</p>
<h3> <span class="mw-headline" id=".E6.89.A9.E5.B1.95.E6.8E.A5.E5.8F.A3"> 扩展接口 </span></h3>
<p>您可以创建构建在一或多个接口之上的接口。
新接口称为<em>子接口</em>，
所继承的全部接口均为其<em>超接口</em>。
</p><p>使用 <code><strong>extends</strong></code> 关键词
可指定作为基础的一或多个接口。
下面是创建 <code>Hashable</code> 子接口的例子：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">interface </span><span class="typ">HashablePoint</span><span class="pln"> </span><span class="kwd">extends</span><span class="pln"> </span><span class="typ">Hashable</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">num</span><span class="pln"> x</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></pre>
<div class="note">
<p><strong>注：</strong>
技术上而言，接口没有
<code>x</code>、<code>y</code> 等实例变量。
看起来是实例变量的部分，实际上是
声明
<a href="#classes-getters-and-setters"><code>getter</code> 与 <code>setter</code> 方法</a>的快捷方式。
</p>
</div>
<p>下面是实现子接口
并检查类型的例子：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">Point</span><span class="pln"> </span><span class="kwd">implements</span><span class="pln"> </span><span class="typ">HashablePoint</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">num</span><span class="pln"> x</span><span class="pun">,</span><span class="pln"> y</span><span class="pun">;</span><span class="pln"> </span><span class="com">// HashablePoint 所需</span><span class="pln">

  </span><span class="com">// Hashable 所需</span><span class="pln">
  </span><span class="kwd">int</span><span class="pln"> hashCode</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="pun">...</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">void</span><span class="pln"> main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">Point</span><span class="pln"> p </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Point</span><span class="pun">();</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">p is </span><span class="typ">Point</span><span class="pun">);</span><span class="pln">          </span><span class="com">// true</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">p is </span><span class="typ">Hashable</span><span class="pun">);</span><span class="pln">       </span><span class="com">// true</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">p is </span><span class="typ">HashablePoint</span><span class="pun">);</span><span class="pln">  </span><span class="com">// true</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><span id="interfaces-default-class"></span>
</p>
<h3> <span class="mw-headline" id=".E5.AE.9A.E4.B9.89.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0.E4.B8.8E.E9.BB.98.E8.AE.A4.E7.B1.BB"> 定义构造函数与默认类 </span></h3>
<p>接口只要指定了<em>默认类</em>，
就可以定义构造函数。
</p>
<div class="note">
<p><strong>注：</strong>
很多 Dart API 是作为有默认类的接口实现的。
如所有<a href="#built-in-types">内置类型</a>，
包括 <a href="#numbers"><code>num</code> 与 <code>int</code></a> 均为接口。
</p>
</div>
<p>使用 <code>default</code> 关键字可指定
默认类。
例如：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">interface </span><span class="typ">ObjectCache</span><span class="pln"> </span><span class="kwd">default</span><span class="pln"> </span><span class="typ">MemoryCache</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">ObjectCache</span><span class="pun">();</span><span class="pln">
  </span><span class="pun">...</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>默认类的代码可以是这样：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">MemoryCache</span><span class="pln"> </span><span class="kwd">implements</span><span class="pln"> </span><span class="typ">ObjectCache</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="pun">...</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>通过接口调用构造函数
会导致接口默认类的等效构造函数
被调用。
例如：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">var cache </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ObjectCache</span><span class="pun">();</span><span class="pln"> </span><span class="com">// 与 new MemoryCache() 相同</span></pre>
<p><span id="interfaces-summary"></span>
</p>
<h3> <span class="mw-headline" id=".E6.8E.A5.E5.8F.A3.E5.B0.8F.E7.BB.93"> 接口小结 </span></h3>
<p>Dart 中到处都是接口，
包括内置类型与
Dart 标准库中所定义的很多类型。
由于 Dart 接口可以有默认类，
您可以使用接口构造函数。
</p><p><span id="generics"></span>
</p>
<h2> <span class="mw-headline" id=".E6.B3.9B.E5.9E.8B"> 泛型 </span></h2>
<p>如果您仔细阅读了 API 文档中基本数组类型 
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/List.html">List</a></code> 的相关内容，
会发现其类型实际上是 <code><strong>List&lt;E&gt;</strong></code>。
<code>&lt;...&gt;</code> 符号将 <code>List</code> 标记为 <em>泛型</em>
（或称 <em>参数化类型</em>）—一种可以声明
常规类型参数的类型。
</p>
<h3> <span class="mw-headline" id=".E4.B8.BA.E4.BD.95.E8.A6.81.E4.BD.BF.E7.94.A8.E6.B3.9B.E5.9E.8B.EF.BC.9F"> 为何要使用泛型？ </span></h3>
<p>由于 Dart 中类型可选，
您不会遇到<em>必须</em>使用泛型的情况。
不过有时您可能会<em>想用</em>泛型
或其他类型：
类型（不论是否为泛型）有助于代码文档及注释的编写，
能简便地表达您的意图。
</p><p>例如，
如果您打算让列表只包含字符串，
可以将其定义为 <code><strong>List&lt;String&gt;</strong></code>
（读作“List of String”——字符串的列表）。
这样您和其他程序员，以及您的工具
（如 Dart Editor 与强制模式下的 Dart VM）
将能侦测到，将非字符串量赋值给列表
可能有误。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">&gt;</span><span class="pln"> names </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">&gt;();</span><span class="pln">
names</span><span class="pun">.</span><span class="pln">addAll</span><span class="pun">([</span><span class="str">'Seth'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Kathy'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Lars'</span><span class="pun">]);</span><span class="pln">
</span><span class="pun">...</span><span class="pln">
names</span><span class="pun">.</span><span class="pln">add</span><span class="pun">(</span><span class="lit">42</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 强制模式下会失败（生产模式下可以通过）</span></pre>
<p>另一个使用泛型的理由是
减少代码的重复量。
泛型允许您将单个接口及实现
在多种类型间共享，
同时仍保有强制模式的优势
并进行静态分析预警。
例如，
假设您创建了用于缓存对象的接口：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">interface </span><span class="typ">ObjectCache</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">Object</span><span class="pln"> getByKey</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> key</span><span class="pun">);</span><span class="pln">
  setByKey</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> key</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Object</span><span class="pln"> value</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>您发现需要该接口的字符串专用版本，
因此您又创建了另一个接口：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">interface </span><span class="typ">StringCache</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">String</span><span class="pln"> getByKey</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> key</span><span class="pun">);</span><span class="pln">
  setByKey</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> key</span><span class="pun">,</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> value</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>在此之后，您又决定想要该接口的数字专用版本……
后续情况你懂的。
</p><p>泛型可以免除挨个创建这些接口的麻烦。
您只需创建单个接口，并读入类型参数：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">interface </span><span class="typ">Cache</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  T getByKey</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> key</span><span class="pun">);</span><span class="pln">
  setByKey</span><span class="pun">(</span><span class="typ">String</span><span class="pln"> key</span><span class="pun">,</span><span class="pln"> T value</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>这段代码中的 <code>T</code> 是替代类型。
可以看作开发者可能会特别定义的占位符。
</p><p><span id="generics-literals"></span>
</p>
<h3> <span class="mw-headline" id=".E4.BD.BF.E7.94.A8.E9.9B.86.E5.90.88.E5.B8.B8.E9.87.8F"> 使用集合常量 </span></h3>
<p>内置的两种集合类型——
<a href="#lists">列表</a> 与
<a href="#maps">映射</a>
——均已参数化。
参数化的常量与之前见过的常量几乎没有区别，
只需要在左括号前加上 <code><strong>&lt;<em>type</em>&gt;</strong></code>。
例如：
</p><p><span class="prettyprint lang-dart linenums:0">
</span></p>
<pre>List&lt;String&gt; names = <b>&lt;String&gt;</b>['Seth', 'Kathy', 'Lars'];
Map&lt;String, String&gt; pages = <b>&lt;String&gt;</b>{ // 指定<b>值</b>的类型：String
    'index.html':'主页',  // （<b>键</b>也隐含了类型 String）
    'robots.txt':'给网络蜘蛛看的',
    'humans.txt':'咱是人类，不是机器' };
</pre>
<p>
</p>
<div class="note">
<p><strong>注：</strong>
映射常量的<em>键</em>总是字符串类型。
花括号前的类型指定的是映射<em>值</em>的类型。
</p>
</div>
<p><span id="generics-constructors"></span>
</p>
<h3> <span class="mw-headline" id=".E4.BD.BF.E7.94.A8.E6.9E.84.E9.80.A0.E5.87.BD.E6.95.B0"> 使用构造函数 </span></h3>
<p>使用构造函数时，若要指定一或多个类型，
请将类型放在类名或接口名后面的尖括号
（<code>&lt;...&gt;</code>）中。
例如：
</p><p><span class="prettyprint lang-dart linenums:0">
</span></p>
<pre>List&lt;String&gt; names = new List<b>&lt;String&gt;</b>();
names.addAll(['Seth', 'Kathy', 'Lars']);
Set&lt;String&gt; nameSet = new Set<b>&lt;String&gt;</b>.from(names);
</pre>
<p>
</p><p>下面的代码可创建
键为整数、值为 <code>View</code> 类型的映射：
</p><p><span class="prettyprint lang-dart linenums:0">
</span></p>
<pre>Map&lt;int, View&gt; views = new Map<b>&lt;int, View&gt;</b>();
</pre>
<p>
</p><p><span id="generics-collections"></span>
</p>
<h3> <span class="mw-headline" id=".E6.B3.9B.E9.9B.86.E5.90.88.E5.8F.8A.E5.85.B6.E5.8C.85.E5.90.AB.E7.9A.84.E7.B1.BB.E5.9E.8B"> 泛集合及其包含的类型 </span></h3>
<p>Dart 中的泛型已经过<em>具体化</em>——
它们会在运行时携带类型信息。
例如，即使是在生产模式下，
您也可以测试集合类型：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">&gt;</span><span class="pln"> names </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">&gt;();</span><span class="pln">
names</span><span class="pun">.</span><span class="pln">addAll</span><span class="pun">([</span><span class="str">'Seth'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Kathy'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Lars'</span><span class="pun">]);</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">names is </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">String</span><span class="pun">&gt;);</span><span class="pln">           </span><span class="com">// true</span></pre>
<p>不过 <code><strong>is</strong></code> 表达式
只能检查<em>集合</em>的类型—而不是
其内部的对象。
在生产模式中，
<code>List&lt;String&gt;</code> 可以包含一些非字符串项。
这时的处理方案是
检查各项的类型
或将项目操作代码包含在<a href="#exceptions">异常处理语句</a>中。
</p>
<div class="note">
<p><strong>注：</strong>
与此相反，
Java 中的泛型使用了 <code><em>erasure</em></code> 类型，
也就是说泛型参数在运行时会被移除。
Java 中可以测试对象是不是 <code>List</code>，
但不能测试它是不是 <code>List&lt;String&gt;</code>。
</p>
</div>
<p><span id="generics-summary"></span>
</p>
<h3> <span class="mw-headline" id=".E6.B3.9B.E5.9E.8B.E5.B0.8F.E7.BB.93"> 泛型小结 </span></h3>
<p>关于泛型的详细信息请参见《<a rel="nofollow" class="external text" href="http://www.dartlang.org/articles/optional-types/">Dart 中的可选类型</a>》一文。
</p><p><span id="libraries"></span>
</p>
<h2> <span class="mw-headline" id=".E5.BA.93.E4.B8.8E.E5.8F.AF.E8.AE.BF.E9.97.AE.E6.80.A7"> 库与可访问性 </span></h2>
<p>本章讲解如何使用
<a href="#libraries-import">导入</a>（<code><strong>#import</strong></code>）、
<a href="#libraries-source">包含</a>（<code><strong>#source</strong></code>）以及
<a href="#libraries-library">新库</a>（<code><strong>#library</strong></code>）
指令，
可帮助您
创建模块化且可共享的代码库。
库的作用不仅是提供 API，
还是隐私单位：
它们可以隐藏实现的细节，如私有变量。
</p><p><b>每个 Dart 应用都是一个库</b>，
即使它没有使用 <code>#library</code> 指令。
</p>
<div class="note">
<p><b>注：</b>
Dart 中的库体系 <b>将有所变动</b>。
本章描述的是目前的工作方式。
</p>
</div>
<p><span id="libraries-import"></span>
</p>
<h3> <span class="mw-headline" id=".E4.BD.BF.E7.94.A8.E5.BA.93"> 使用库 </span></h3>
<p>使用 <code><strong>#import</strong></code>
可指定将一个库的命名空间
用在另一个库的作用域内。
</p><p>Dart web 应用通常会用到
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/html.html">dart:html</a></code>
库，可以这样导入：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'dart:html'</span><span class="pun">);</span></pre>
<p><code>#import</code> 所需的唯一参数是指向库的
URI。
对于内置库，
URI 以特别的 <code>dart:</code> 前缀区别。
对于其他库，
URI 相对于当前目录。
（未来还将允许指定 web 服务器上的文件。）
例如：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'dart:io'</span><span class="pun">);</span><span class="pln">
</span><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'mylib/mylib.dart'</span><span class="pun">);</span><span class="pln">
</span><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'../../util/utilslib.dart'</span><span class="pun">);</span></pre>
<p><span id="libraries-prefix"></span>
</p>
<h4> <span class="mw-headline" id=".E6.8C.87.E5.AE.9A.E5.89.8D.E7.BC.80"> 指定前缀 </span></h4>
<p>如果您导入的两个库的标识符有冲突，
可以为其中一个或两者都指定前缀。
例如，如果 <code>library1</code> 与 <code>library2</code> 均定义了 <code>Element</code>，
可以这样编写代码：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'lib1/library1.dart'</span><span class="pun">);</span><span class="pln">
</span><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'lib2/library2.dart'</span><span class="pun">,</span><span class="pln"> prefix</span><span class="pun">:</span><span class="str">'lib2'</span><span class="pun">);</span><span class="pln">
</span><span class="pun">...</span><span class="pln">
var element1 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Element</span><span class="pun">();</span><span class="pln">      </span><span class="com">// 使用 library1 中的 Element</span><span class="pln">
var element2 </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> lib2</span><span class="pun">.</span><span class="typ">Element</span><span class="pun">();</span><span class="pln"> </span><span class="com">// 使用 library2 中的 Element</span></pre>
<p><span id="libraries-library"></span>
</p>
<h3> <span class="mw-headline" id=".E5.BA.93.E7.9A.84.E5.AE.9E.E7.8E.B0"> 库的实现 </span></h3>
<p>使用 <code><a href="#libraries-source">#source</a></code>
（亦称 <em>包含指令</em>）
可指定属于当前库的文件，
而 <code><a href="#libraries-library">#library</a></code>
可指定文件实现了一个库。
</p><p><span id="libraries-source"></span>
</p>
<h4> <span class="mw-headline" id=".E5.B0.86.E6.96.87.E4.BB.B6.E4.B8.8E.E5.BD.93.E5.89.8D.E5.BA.93.E5.85.B3.E8.81.94"> 将文件与当前库关联 </span></h4>
<p>您可以将库的实现放在多个 .dart 文件中，
并在该库的主文件中使用 <code><strong>#source</strong></code> 关联。
</p>
<div class="note">
<p><strong>被包含的文件不能含有指令。</strong>
库中必须有一个文件
包含库所需的所有指令
（如 <code>#import</code> 和 <code>#library</code>）。
</p>
</div>
<p>下面是一个例子：
<span class="prettyprint lang-dart linenums:0">
</span></p>
<pre><em>// 文件 Ballgame.dart 中的内容</em>
#import('dart:html');

#source('Ball.dart');
#source('Util.dart');
...
main() {
  ...
}
</pre>
<p>
</p><p>该例中，Ball.dart 与 Util.dart 会被编译进
Ballgame.dart 这个库当中。
Ballgame.dart 没有 <code>#library</code> 语句，
但请记住，每个 Dart 应用都是隐式的库。
</p><p><span id="libraries-library"></span>
</p>
<h4> <span class="mw-headline" id=".E5.A3.B0.E6.98.8E.E5.BA.93"> 声明库 </span></h4>
<p>要明确声明一个库，可以使用 <code><strong>#library</strong></code> 语句。
例如：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pun">#</span><span class="kwd">library</span><span class="pun">(</span><span class="str">'slider_sample'</span><span class="pun">);</span><span class="pln">           </span><span class="com">// 声明这是一个库。</span><span class="pln">

</span><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'dart:html'</span><span class="pun">);</span><span class="pln">                </span><span class="com">// 该库用到了 html 库...</span><span class="pln">
</span><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'../ui_lib/view/view.dart'</span><span class="pun">);</span><span class="pln"> </span><span class="com">// ...和 view 库。</span><span class="pln">

</span><span class="pun">#</span><span class="pln">source</span><span class="pun">(</span><span class="str">'SliderSample.dart'</span><span class="pun">);</span><span class="pln">        </span><span class="com">// 从 SliderSample.dart 中获取代码。</span></pre>
<div class="note">
<p><b>注：</b>
<code>#library</code> 语句中的字符串目前用不到。
</p>
</div>
<p><span id="libraries-private-members"></span>
</p>
<h4> <span class="mw-headline" id=".E5.A3.B0.E6.98.8E.E7.A7.81.E6.9C.89.E6.88.90.E5.91.98"> 声明私有成员 </span></h4>
<p>如果标识符以下划线开头，
便是所属库的私有成员。
例如，
在下面的代码中，<code>Incrementer</code> 类
有一个名为 <code>_hiddenNum</code>
的实例变量。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pun">#</span><span class="kwd">library</span><span class="pun">(</span><span class="str">'HidingLibrary'</span><span class="pun">);</span><span class="pln">

</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">Incrementer</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">num</span><span class="pln"> _hiddenNum </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
  
  </span><span class="kwd">void</span><span class="pln"> incrementNum</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    _hiddenNum</span><span class="pun">++;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
  
  </span><span class="kwd">void</span><span class="pln"> printNum</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    print</span><span class="pun">(</span><span class="str">"隐含的数字为 $_hiddenNum"</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">void</span><span class="pln"> main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  var o </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Incrementer</span><span class="pun">();</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"在这里可以读取到 _hiddenNum (${o._hiddenNum})。"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><code>main()</code> 方法可以引用 <code>_hiddenNum</code>
因为它与 <code>Incrementer</code> 处于同一个库当中。
但在该库以外，<code>_hiddenNum</code> 将不可访问，
即便是在 <code>Incrementer</code> 的子类中。
</p><p>例如，下面的代码无法使用 <code>_hiddenNum</code>
因为与 <code>Incrementer</code> 分别处于不同的库当中
（在库 <code>HidingLib/hider.dart</code> 中实现）：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pun">#</span><span class="kwd">library</span><span class="pun">(</span><span class="str">'SubclassingLibrary'</span><span class="pun">);</span><span class="pln">
</span><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'../HidingLib/hider.dart'</span><span class="pun">);</span><span class="pln">

</span><span class="com">// 此类在 Incrementer 所处库之外，因此无法使用 _hiddenNum</span><span class="pln">
</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">DoubleIncrementer</span><span class="pln"> </span><span class="kwd">extends</span><span class="pln"> </span><span class="typ">Incrementer</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">void</span><span class="pln"> incrementNum</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="com">//_hiddenNum = _hiddenNum + 2; // 无法解析 _hiddenNum</span><span class="pln">
    </span><span class="kwd">super</span><span class="pun">.</span><span class="pln">incrementNum</span><span class="pun">();</span><span class="pln">          </span><span class="com">// 只能这样令 _hiddenNum 自增</span><span class="pln">
    </span><span class="kwd">super</span><span class="pun">.</span><span class="pln">incrementNum</span><span class="pun">();</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><span id="libraries-summary"></span>
</p>
<h3> <span class="mw-headline" id=".E5.BA.93.E4.B8.8E.E5.8F.AF.E8.A7.81.E6.80.A7.E5.B0.8F.E7.BB.93"> 库与可见性小结 </span></h3>
<p>如果需要使用库，请用
<code><strong>#import</strong></code>；如果需要将文件拉取到库中，请用
<code><strong>#source</strong></code>；如果需要声明您正在实现一个库，
请用 <code><strong>#library</strong></code>。
以下划线（<code>_</code>）命名的成员是库的私有成员。
</p><p><span id="isolates"></span>
</p>
<h2> <span class="mw-headline" id=".E9.9A.94.E7.A6.BB"> 隔离 </span></h2>
<p>Dart 中的所有代码都在隔离的上下文中执行。
您可以使用额外的隔离进行并发编程，
以及更安全地执行第三方代码。
</p>
<h3> <span class="mw-headline" id=".E9.9A.94.E7.A6.BB.E6.A6.82.E5.BF.B5"> 隔离概念 </span></h3>
<p>每个隔离都有自己的 heap，即它在内存中的全部值，
包括全局变量，只能在隔离内部使用。
在隔离之间通讯的唯一途径是传递消息。
消息通过端口发送。
</p><p>消息的内容可以是：
</p>
<ul><li> 基本值（<code>null</code>、<code>num</code>、<code>bool</code>、<code>double</code>、<code>String</code>）
</li><li> <code>SendPort</code> 的实例
</li><li> 列表或映射，其元素为上述任意类型，或是其他列表和映射
</li><li> <a href="#sending-any-type-of-object">特殊情况</a>下可发送任意类型的对象
</li></ul>
<p>列表与映射可以循环引用其自身。
每条消息在发送到其他隔离时都会产生副本，以确保
一个隔离无法更改其他隔离中消息的状态。
</p><p>根据实现的不同，隔离可能分开在不同进程或线程中执行。
对于 web 应用，如果可用，隔离可以编译为
Web worker。
</p>
<h3> <span class="mw-headline" id=".E4.BD.BF.E7.94.A8.E9.9A.94.E7.A6.BB"> 使用隔离 </span></h3>
<p>要使用隔离，您需要导入 <code>isolate</code> 库，
创造新隔离，并发送与接收消息。
</p>
<h4> <span class="mw-headline" id=".E5.AF.BC.E5.85.A5_isolate_.E5.BA.93"> 导入 <code>isolate</code> 库 </span></h4>
<p>隔离相关的 API 可以在 <code>dart:isolate</code> 库中找到。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'dart:isolate'</span><span class="pun">);</span></pre>
<h4> <span class="mw-headline" id=".E5.88.9B.E9.80.A0.E6.96.B0.E9.9A.94.E7.A6.BB"> 创造新隔离 </span></h4>
<p>任意顶级函数或静态方法
都是有效的隔离切入点。
切入点不应要求参数输入，且应返回 <code>void</code>。
使用函数末尾作为隔离切入点是不合法的。
将切入点传递给
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_isolate.html#spawnFunction">spawnFunction()</a></code>。
</p>
<div class="note">
<p><strong>注：</strong>dart2js 尚不支持将静态方法作为隔离切入点。
</p>
</div>
<pre class="prettyprint lang-dart linenums:0"><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'dart:isolate'</span><span class="pun">);</span><span class="pln">

runInIsolate</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"来自隔离中的问候！"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  spawnFunction</span><span class="pun">(</span><span class="pln">runInIsolate</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>我们计划支持从 URI 所指向的代码创造隔离。
</p>
<h4> <span class="mw-headline" id=".E5.8F.91.E9.80.81.E6.B6.88.E6.81.AF"> 发送消息 </span></h4>
<p>可通过
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_isolate/SendPort.html">SendPort</a></code>
将消息发送到隔离。
<code>spawnFunction()</code> 方法会返回指向其 <code>SendPort</code> 的句柄。
</p><p>如果只是要发送一条消息，可以使用
<code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_isolate/SendPort.html#send">send()</a></code>。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'dart:isolate'</span><span class="pun">);</span><span class="pln">

echo</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="com">// 在此接收消息，参见下一章节</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">SendPort</span><span class="pln"> sendPort </span><span class="pun">=</span><span class="pln"> spawnFunction</span><span class="pun">(</span><span class="pln">echo</span><span class="pun">);</span><span class="pln">
  sendPort</span><span class="pun">.</span><span class="pln">send</span><span class="pun">(</span><span class="str">"来自 main 的问候"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><span id="sending-any-type-of-object"></span>
</p>
<h4> <span class="mw-headline" id=".E5.8F.91.E9.80.81.E4.BB.BB.E6.84.8F.E7.B1.BB.E5.9E.8B.E7.9A.84.E5.AF.B9.E8.B1.A1"> 发送任意类型的对象 </span></h4>
<p>特殊情况下（如在 Dart VM 内部使用 <code>spawnFunction()</code>）
可以将任意类型的对象实例发送给隔离。
对象消息在发送时会产生副本。
</p><p>编译到 JavaScript 时，
尚未实现将任意对象实例发送给隔离，
即使使用了 <code>spawnFunction()</code>。
</p>
<h4> <span class="mw-headline" id=".E6.8E.A5.E6.94.B6.E6.B6.88.E6.81.AF"> 接收消息 </span></h4>
<p>使用 <code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_isolate/ReceivePort.html">ReceivePort</a></code>
可接收发往隔离的消息。可以从 <code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_isolate.html#get:port">port</a></code>
属性获取指向 <code>ReceivePort</code> 的句柄。
然后使用传递给 <code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_isolate/ReceivePort.html#receive">receive()</a></code>
方法的回调函数处理新消息。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'dart:isolate'</span><span class="pun">);</span><span class="pln">

echo</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  port</span><span class="pun">.</span><span class="pln">receive</span><span class="pun">((</span><span class="pln">msg</span><span class="pun">,</span><span class="pln"> </span><span class="typ">SendPort</span><span class="pln"> reply</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    print</span><span class="pun">(</span><span class="str">"我收到了：$msg"</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">});</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">SendPort</span><span class="pln"> sendPort </span><span class="pun">=</span><span class="pln"> spawnFunction</span><span class="pun">(</span><span class="pln">echo</span><span class="pun">);</span><span class="pln">
  sendPort</span><span class="pun">.</span><span class="pln">send</span><span class="pun">(</span><span class="str">"来自 main 的问候"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<h4> <span class="mw-headline" id=".E6.8E.A5.E6.94.B6.E5.9B.9E.E5.A4.8D"> 接收回复 </span></h4>
<p>使用 SendPort 的 <code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_isolate/SendPort.html#call">call()</a></code>
方法可方便地发送消息与接收回复。
<code>call()</code> 方法会返回 <code><a rel="nofollow" class="external text" href="http://api.dartlang.org/dart_core/Future.html">Future</a></code> 作为回复。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pun">#</span><span class="kwd">import</span><span class="pun">(</span><span class="str">'dart:isolate'</span><span class="pun">);</span><span class="pln">

echo</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  port</span><span class="pun">.</span><span class="pln">receive</span><span class="pun">((</span><span class="pln">msg</span><span class="pun">,</span><span class="pln"> </span><span class="typ">SendPort</span><span class="pln"> reply</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    reply</span><span class="pun">.</span><span class="pln">send</span><span class="pun">(</span><span class="str">"我收到了：$msg"</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">});</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">SendPort</span><span class="pln"> sendPort </span><span class="pun">=</span><span class="pln"> spawnFunction</span><span class="pun">(</span><span class="pln">echo</span><span class="pun">);</span><span class="pln">
  sendPort</span><span class="pun">.</span><span class="pln">call</span><span class="pun">(</span><span class="str">"来自 main 的问候"</span><span class="pun">).</span><span class="pln">then</span><span class="pun">((</span><span class="pln">reply</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    print</span><span class="pun">(</span><span class="pln">reply</span><span class="pun">);</span><span class="pln">    </span><span class="com">// 我收到了：来自 main 的问候</span><span class="pln">
  </span><span class="pun">});</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><span id="typedefs"></span>
</p>
<h2> <span class="mw-headline" id=".E7.B1.BB.E5.9E.8B.E5.AE.9A.E4.B9.89"> 类型定义 </span></h2>
<p>在 Dart 中，函数与字符串和数字一样，也是对象。
<code><em>typedef</em></code>，或称 <em>函数类型别名</em>，可以对函数命名，
以便在声明语句与返回类型时使用。
当函数类型被赋值给变量时，<code>typedef</code>
会保留类型信息。
</p><p>请看下述代码，其中未使用 <code>typedef</code>。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">class</span><span class="pln"> </span><span class="typ">SortedCollection</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">Function</span><span class="pln"> compare</span><span class="pun">;</span><span class="pln">

  </span><span class="typ">SortedCollection</span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> f</span><span class="pun">(</span><span class="typ">Object</span><span class="pln"> a</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Object</span><span class="pln"> b</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    compare </span><span class="pun">=</span><span class="pln"> f</span><span class="pun">;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">int</span><span class="pln"> sort</span><span class="pun">(</span><span class="typ">Object</span><span class="pln"> a</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Object</span><span class="pln"> b</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> </span><span class="pun">...</span><span class="pln">&nbsp;</span><span class="pun">;</span><span class="pln">

main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">SortedCollection</span><span class="pln"> collection </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">SortedCollection</span><span class="pun">(</span><span class="pln">sort</span><span class="pun">);</span><span class="pln">

  </span><span class="com">// 我们只知道 compare 是一个函数，但它是哪种类型的函数？</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">collection</span><span class="pun">.</span><span class="pln">compare is </span><span class="typ">Function</span><span class="pun">);</span><span class="pln">  </span><span class="com">// true</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>在将 <code>f</code> 赋值给 <code>compare</code> 时，其类型信息丢失。
<code>f</code> 的类型为 <code>(Object, Object) → int</code>，而
<code>compare</code> 的类型为 <code>Function</code>。
如果修改代码，使用确切的名称并保留类型信息，
开发人员与工具便都能利用该信息。
</p><p>加上 <code>typedef</code> 可让 Dart 保留类型信息。
</p><p><span class="prettyprint lang-dart linenums:0">
</span></p>
<pre><b>typedef int Compare(Object a, Object b);</b>

class SortedCollection {
  Compare compare;

  SortedCollection(this.compare);
}

int sort(Object a, Object b) =&gt; ...&nbsp;;

main() {
  SortedCollection collection = new SortedCollection(sort);
  print(collection.compare is Function);  // true
  print(collection.compare is Compare);   // true
}
</pre>
<p>
</p>
<div class="note">
<p><strong>注：</strong> 目前，<code>typedef</code> 仅限对函数类型使用。
未来版本的语言规范中可能会有变化。
</p>
</div>
<p>由于 <code>typedef</code> 只是别名，它们也提供了检查任意函数类型的途径。
例如：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">typedef</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> </span><span class="typ">Compare</span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> a</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> b</span><span class="pun">);</span><span class="pln">

</span><span class="kwd">int</span><span class="pln"> sort</span><span class="pun">(</span><span class="kwd">int</span><span class="pln"> a</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> b</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> a </span><span class="pun">-</span><span class="pln"> b</span><span class="pun">;</span><span class="pln">

main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">sort is </span><span class="typ">Compare</span><span class="pun">);</span><span class="pln">  </span><span class="com">// true!</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><code>typedef</code> 还可以参数化。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="kwd">typedef</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> </span><span class="typ">Compare</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">T a</span><span class="pun">,</span><span class="pln"> T b</span><span class="pun">);</span><span class="pln">

</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">SortedCollection</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">Compare</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span><span class="pln"> compare</span><span class="pun">;</span><span class="pln">
  </span><span class="typ">SortedCollection</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">compare</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">SortedCollection</span><span class="pun">&lt;</span><span class="kwd">int</span><span class="pun">&gt;</span><span class="pln"> s </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">SortedCollection</span><span class="pun">&lt;</span><span class="kwd">int</span><span class="pun">&gt;((</span><span class="pln">a</span><span class="pun">,</span><span class="pln">b</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln"> a </span><span class="pun">-</span><span class="pln"> b</span><span class="pun">);</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">s</span><span class="pun">.</span><span class="pln">compare is </span><span class="typ">Compare</span><span class="pun">&lt;</span><span class="kwd">int</span><span class="pun">&gt;);</span><span class="pln">  </span><span class="com">// true</span><span class="pln">
  print</span><span class="pun">(</span><span class="pln">s</span><span class="pun">.</span><span class="pln">compare</span><span class="pun">(</span><span class="str">'a'</span><span class="pun">,</span><span class="str">'b'</span><span class="pun">));</span><span class="pln">  </span><span class="com">// 强制模式下会抛出异常</span><span class="pln">
</span><span class="pun">}</span></pre>
<p><span id="comments"></span>
</p>
<h2> <span class="mw-headline" id=".E6.B3.A8.E9.87.8A"> 注释 </span></h2>
  <p>Dart 支持单行注释、多行注释以及文档注释。

</p><h3> <span class="mw-headline" id=".E5.8D.95.E8.A1.8C.E6.B3.A8.E9.87.8A"> 单行注释 </span></h3>
<p>单行注释以 <code>//</code> 开头。
<code>//</code> 与行尾之间的所有内容都会被 Dart 编译器忽略。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="com">// TODO: 以抽象的骆马欢迎方式重构？</span><span class="pln">
  print</span><span class="pun">(</span><span class="str">"欢迎造访我的骆马农场!"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>
<h3> <span class="mw-headline" id=".E5.A4.9A.E8.A1.8C.E6.B3.A8.E9.87.8A"> 多行注释 </span></h3>
<p>多行注释以 <code>/*</code> 开头，以 <code>*/</code> 结尾。
<code>/*</code> 与 <code>*/</code> 直接的所有内容都会被
Dart 编译器忽略（除非该注释为文档注释，参见下文）。
多行注释可以嵌套。
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="pln">main</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="com">/*
   * 任务很多。还在考虑养鸡。

  Llama larry = new Llama();
  larry.feed();
  larry.exercise();
  larry.clean();
   */</span><span class="pln">
</span><span class="pun">}</span></pre>
<h3> <span class="mw-headline" id=".E6.96.87.E6.A1.A3.E6.B3.A8.E9.87.8A"> 文档注释 </span></h3>
<p>文档注释是以 <code>/**</code> 开头的多行注释。
Dart 编译器将忽略文档注释中除了括号内部分以外的所有文字。
您可以使用方括号在注释中嵌入类、方法以及字段的链接。
方括号中的名称将被解析为所引用程序元素的词法作用范围。
</p><p>下面是引用其他类与参数的文档注释示例：
</p>
<pre class="prettyprint lang-dart linenums:0"><span class="com">/**
 * 骆马 (Lama glama) 是经驯化的南美骆驼，
 * 自前西班牙时期起被安第斯山脉土著广泛用于
 * 肉类生产与驮运。
 */</span><span class="pln">
</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">Llama</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="typ">String</span><span class="pln"> name</span><span class="pun">;</span><span class="pln">

  </span><span class="com">/**
   * 给骆马喂 [Food]。通常每周一捆干草。
   */</span><span class="pln">
  feed</span><span class="pun">(</span><span class="typ">Food</span><span class="pln"> food</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="pun">...</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  </span><span class="com">/**
   * 让骆马做 [timeLimit] 分钟的 [activity] 锻炼。
   */</span><span class="pln">
  exercise</span><span class="pun">(</span><span class="typ">Activity</span><span class="pln"> activity</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> timeLimit</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="pun">...</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>您可以使用 SDK 中附带的 dartdoc 工具解析
Dart 代码并生成 HTML。下面是 dartdoc 输出内容的例子。
</p>
<pre class="prettyprint lang-html linenums:0"><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"doc"</span><span class="tag">&gt;</span><span class="pln">
</span><span class="tag">&lt;p&gt;</span><span class="pln">给骆马喂 </span><span class="tag">&lt;a</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"crossref"</span><span class="pln"> </span><span class="atn">href</span><span class="pun">=</span><span class="atv">"../llama/Food.html"</span><span class="tag">&gt;</span><span class="pln">Food</span><span class="tag">&lt;/a&gt;</span><span class="pln">。通常每周一捆干草。</span><span class="tag">&lt;/p&gt;</span><span class="pln">
</span><span class="tag">&lt;pre</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"source"</span><span class="tag">&gt;</span><span class="pln">
feed(Food food) {
  // ...
}
</span><span class="tag">&lt;/pre&gt;</span><span class="pln">
</span><span class="tag">&lt;/div&gt;</span></pre>
<p>请注意 <code>[Food]</code> 是如何从文档注释
转换为指向 Food 类的 API 文档的 HTML 链接的。</p>
</div>
</body>
</html>

